P4 to Git Change 1144775 by yaxunl@yaxunl_stg_win50 on 2015/04/27 12:11:07

ECR #304775 - Wave limiter: Fix crash in CompuBenchCL video composition due to profiling data not collected correctly.

	Gpuvirtual.cpp only collects profiling data when all events have profiling enabled. Fixed it by adding a member to indicate at least one event has profiling enabled and collect profiling data.

	Improved adptation by changing waves/simd only when the last change has been enforced. Also detecting discontinuities in measured data and discard them.

Affected files ...

... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#359 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.hpp#129 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.cpp#3 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.hpp#2 edit
... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.hpp#230 edit


[ROCm/clr commit: b5a5c65e53]
This commit is contained in:
foreman
2015-04-27 12:21:03 -04:00
parent bada096dbe
commit 31ec44ded5
5 changed files with 75 additions and 28 deletions
@@ -7,6 +7,9 @@
#include "os/os.hpp"
#include "utils/flags.hpp"
#include <cstdlib>
using namespace std;
namespace gpu {
uint WaveLimiter::MaxWave;
@@ -14,14 +17,18 @@ uint WaveLimiter::WarmUpCount;
uint WaveLimiter::AdaptCount;
uint WaveLimiter::RunCount;
uint WaveLimiter::AbandonThresh;
uint WaveLimiter::DscThresh;
void WaveLimiter::clearData() {
waves_ = MaxWave;
countAll_ = 0;
clear(counts_);
clear(sum_);
clear(average_);
clear(measure_);
clear(reference_);
clear(trial_);
clear(ratio_);
discontinuous_ = false;
waveSet_ = false;
dataCount_ = 0;
}
void WaveLimiter::enable() {
@@ -49,17 +56,17 @@ WaveLimiter::WaveLimiter(Kernel *owner) :
MaxWave = GPU_WAVE_LIMIT_MAX_WAVE;
WarmUpCount = GPU_WAVE_LIMIT_WARMUP;
AdaptCount = GPU_WAVE_LIMIT_ADAPT * MaxWave;
AdaptCount = 2 * MaxWave + 1;
RunCount = GPU_WAVE_LIMIT_RUN * MaxWave;
AbandonThresh = GPU_WAVE_LIMIT_ABANDON;
DscThresh = GPU_WAVE_LIMIT_DSC_THRESH;
state_ = WARMUP;
dynRunCount_ = RunCount;
auto size = MaxWave + 1;
counts_.resize(size);
sum_.resize(size);
average_.resize(size);
ratio_.resize(size);
measure_.resize(MaxWave + 1);
reference_.resize(MaxWave + 1);
trial_.resize(MaxWave + 1);
ratio_.resize(MaxWave + 1);
clearData();
if (!flagIsDefault(GPU_WAVE_LIMIT_TRACE)) {
traceStream_.open(std::string(GPU_WAVE_LIMIT_TRACE) + owner_->name() +
@@ -69,6 +76,7 @@ WaveLimiter::WaveLimiter(Kernel *owner) :
waves_ = GPU_WAVES_PER_SIMD;
bestWave_ = MaxWave;
enable_ = false;
waveSet_ = false;
}
WaveLimiter::~WaveLimiter() {
@@ -78,16 +86,34 @@ WaveLimiter::~WaveLimiter() {
}
uint WaveLimiter::getWavesPerSH() const {
waveSet_ = true;
return waves_ * SIMDPerSH_;
}
void WaveLimiter::updateData(ulong time) {
sum_[waves_] += time;
counts_[waves_]++;
average_[waves_] = sum_[waves_] / counts_[waves_];
ratio_[waves_] = average_[waves_] * 100 / average_[MaxWave];
if (average_[bestWave_] > average_[waves_]) {
bestWave_ = waves_;
auto count = dataCount_ - 1;
assert(count < 2 * MaxWave + 1);
assert(time > 0);
if (count % 2 == 0) {
assert(waves_ == MaxWave);
auto pos = count / 2;
measure_[pos] = time;
if (pos > 0) {
auto wave = MaxWave + 1 - pos;
if (abs(static_cast<long>(measure_[pos - 1]) -
static_cast<long>(measure_[pos])) * 100 / measure_[pos] >
DscThresh) {
discontinuous_ = true;
}
reference_[wave] = (time + measure_[pos - 1]) / 2;
ratio_[wave] = trial_[wave] * 100 / reference_[wave];
if (ratio_[bestWave_] > ratio_[wave] && !discontinuous_) {
bestWave_ = wave;
}
}
} else {
assert(waves_ == MaxWave - count / 2);
trial_[waves_] = time;
}
outputTrace();
}
@@ -99,9 +125,8 @@ void WaveLimiter::outputTrace() {
traceStream_ << "[WaveLimiter] " << owner_->name() << " state=" << state_
<< " waves=" << waves_ << " bestWave=" << bestWave_ << '\n';
output(traceStream_, "\n counts = ", counts_);
output(traceStream_, "\n sum = ", sum_);
output(traceStream_, "\n average = ", average_);
output(traceStream_, "\n measure = ", measure_);
output(traceStream_, "\n reference = ", reference_);
output(traceStream_, "\n ratio = ", ratio_);
traceStream_ << "\n\n";
}
@@ -125,13 +150,26 @@ void WaveLimiter::callback(ulong duration) {
clearData();
return;
case ADAPT:
updateData(duration);
if (countAll_ < AdaptCount && ratio_[waves_] < AbandonThresh) {
waves_ = MaxWave - (countAll_ % MaxWave);
return;
assert(duration > 0);
if (waveSet_) {
dataCount_++;
updateData(duration);
waves_ = MaxWave + 1 - dataCount_ / 2;
if (dataCount_ == 1 || (dataCount_ < AdaptCount &&
!discontinuous_ && (dataCount_ % 2 == 0 ||
ratio_[waves_] < AbandonThresh))) {
if (dataCount_ % 2 == 1) {
--waves_;
} else {
waves_ = MaxWave;
}
waveSet_ = false;
return;
}
}
waves_ = bestWave_;
if (countAll_ >= AdaptCount) {
waveSet_ = false;
if (dataCount_ >= AdaptCount) {
dynRunCount_ = RunCount;
} else {
dynRunCount_ = AdaptCount;