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]
Esse commit está contido em:
foreman
2015-04-27 12:21:03 -04:00
commit 31ec44ded5
5 arquivos alterados com 75 adições e 28 exclusões
@@ -403,6 +403,7 @@ VirtualGPU::VirtualGPU(
, schedParamIdx_(0)
, deviceQueueSize_(0)
, hsaQueueMem_(NULL)
, profileEnabled_(false)
{
memset(&cal_, 0, sizeof(CalVirtualDesc));
for (uint i = 0; i < AllEngines; ++i) {
@@ -2804,7 +2805,7 @@ VirtualGPU::awaitCompletion(CommandBatch* cb, const amd::Event* waitingEvent)
amd::Command* head = cb->head_;
// Make sure that profiling is enabled
if (head->profilingInfo().enabled_) {
if (profileEnabled_) {
return profilingCollectResults(cb, waitingEvent);
}
// Mark the first command in the batch as running
@@ -3250,6 +3251,7 @@ VirtualGPU::profilingBegin(amd::Command& command, bool drmProfiling)
// Save the TimeStamp object in the current OCL event
command.setData(ts);
currTs_ = ts;
profileEnabled_ = true;
}
}
@@ -554,6 +554,7 @@ private:
uint deviceQueueSize_; //!< Device queue size
Memory* hsaQueueMem_; //!< Memory for the amd_queue_t object
bool profileEnabled_;//!< Profiling is enabled
};
/*@}*/} // namespace gpu
@@ -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;
@@ -44,10 +44,11 @@ private:
std::vector<char> state_;
};
std::vector<ulong> counts_;
std::vector<ulong> sum_;
std::vector<ulong> average_;
std::vector<ulong> measure_;
std::vector<ulong> reference_;
std::vector<ulong> trial_;
std::vector<ulong> ratio_;
bool discontinuous_; // Measured data is discontinuous
bool enable_;
uint SIMDPerSH_; // Number of SIMDs per SH
@@ -59,12 +60,15 @@ private:
Kernel *owner_;
DataDumper dumper_;
std::ofstream traceStream_;
mutable bool waveSet_;
uint dataCount_;
static uint MaxWave; // Maximum number of waves per SIMD
static uint WarmUpCount; // Number of kernel executions for warm up
static uint AdaptCount; // Number of kernel executions for adapting
static uint RunCount; // Number of kernel executions for normal run
static uint AbandonThresh; // Threshold to abandon adaptation
static uint DscThresh; // Threshold for identifying discontinuities
virtual void callback(ulong duration);
void updateData(ulong time);
+3 -1
Ver Arquivo
@@ -188,10 +188,12 @@ release_on_stg(uint, GPU_WAVE_LIMIT_WARMUP, 100, \
"Set warming up kernel execution count for wave limiter") \
release_on_stg(uint, GPU_WAVE_LIMIT_ADAPT, 1, \
"Set adapting factor for wave limiter") \
release_on_stg(uint, GPU_WAVE_LIMIT_RUN, 40, \
release_on_stg(uint, GPU_WAVE_LIMIT_RUN, 20, \
"Set running factor for wave limiter") \
release_on_stg(uint, GPU_WAVE_LIMIT_ABANDON, 105, \
"Set abandon threshold for wave limiter") \
release_on_stg(uint, GPU_WAVE_LIMIT_DSC_THRESH, 10, \
"Set threshold for rejecting discontinuous data") \
release_on_stg(cstring, GPU_WAVE_LIMIT_DUMP, "", \
"File path prefix for dumping wave limiter output") \
release_on_stg(cstring, GPU_WAVE_LIMIT_TRACE, "", \