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:
@@ -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);
|
||||
|
||||
@@ -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, "", \
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário