P4 to Git Change 1177724 by jatang@jatang-opencl-hsa-stg1 on 2015/08/06 09:59:33

EPR #424562 - Add Averaging algorithm to Wave Limiter.

	1. Extract the algorithms to a sub-class of the wave limiter class.
	2. Add Averaging algorithm

	This averaging algorithm typically improves performance of BasemarkCL wave simulation by 8% on Tonga/Fiji than the current smooth algorithm. This change has not enable the averaging algorithm yet. Follow-up changes should be made to intelligently select which algorithm to use.

Affected files ...

... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.cpp#7 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.hpp#4 edit
This commit is contained in:
foreman
2015-08-06 10:19:59 -04:00
bovenliggende fd5d51f911
commit 8fe485de95
2 gewijzigde bestanden met toevoegingen van 152 en 49 verwijderingen
@@ -14,21 +14,10 @@ namespace gpu {
uint WaveLimiter::MaxWave;
uint WaveLimiter::WarmUpCount;
uint WaveLimiter::AdaptCount;
uint WaveLimiter::RunCount;
uint WaveLimiter::AbandonThresh;
uint WaveLimiter::DscThresh;
void WaveLimiter::clearData() {
waves_ = MaxWave;
countAll_ = 0;
clear(measure_);
clear(reference_);
clear(trial_);
clear(ratio_);
discontinuous_ = false;
dataCount_ = 0;
}
uint WLAlgorithmSmooth::AdaptCount;
uint WLAlgorithmSmooth::AbandonThresh;
uint WLAlgorithmSmooth::DscThresh;
WaveLimiter::WaveLimiter(
Kernel* owner,
@@ -42,21 +31,11 @@ WaveLimiter::WaveLimiter(
auto hwInfo = gpuDev->hwInfo();
setIfNotDefault(SIMDPerSH_, GPU_WAVE_LIMIT_CU_PER_SH,
attrib.numberOfCUsperShaderArray * hwInfo->simdPerCU_);
MaxWave = GPU_WAVE_LIMIT_MAX_WAVE;
WarmUpCount = GPU_WAVE_LIMIT_WARMUP;
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;
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() +
".txt");
@@ -79,7 +58,37 @@ uint WaveLimiter::getWavesPerSH(){
return waves_ * SIMDPerSH_;
}
void WaveLimiter::updateData(ulong time) {
WLAlgorithmSmooth::WLAlgorithmSmooth(Kernel* owner, uint seqNum, bool enable, bool enableDump):
WaveLimiter(owner, seqNum, enable, enableDump) {
AdaptCount = 2 * MaxWave + 1;
AbandonThresh = GPU_WAVE_LIMIT_ABANDON;
DscThresh = GPU_WAVE_LIMIT_DSC_THRESH;
dynRunCount_ = RunCount;
measure_.resize(MaxWave + 1);
reference_.resize(MaxWave + 1);
trial_.resize(MaxWave + 1);
ratio_.resize(MaxWave + 1);
clearData();
}
WLAlgorithmSmooth::~WLAlgorithmSmooth() {
}
void WLAlgorithmSmooth::clearData() {
waves_ = MaxWave;
countAll_ = 0;
clear(measure_);
clear(reference_);
clear(trial_);
clear(ratio_);
discontinuous_ = false;
dataCount_ = 0;
}
void WLAlgorithmSmooth::updateData(ulong time) {
auto count = dataCount_ - 1;
assert(count < 2 * MaxWave + 1);
assert(time > 0);
@@ -108,7 +117,7 @@ void WaveLimiter::updateData(ulong time) {
outputTrace();
}
void WaveLimiter::outputTrace() {
void WLAlgorithmSmooth::outputTrace() {
if (!traceStream_.is_open()) {
return;
}
@@ -122,7 +131,8 @@ void WaveLimiter::outputTrace() {
traceStream_ << "\n\n";
}
void WaveLimiter::callback(ulong duration) {
void WLAlgorithmSmooth::callback(ulong duration) {
dumper_.addData(duration, currWaves_, static_cast<char>(state_));
if (!enable_) {
@@ -207,11 +217,79 @@ void WaveLimiter::DataDumper::addData(ulong time, uint wave, char state) {
state_.push_back(state);
}
WLAlgorithmAvrg::WLAlgorithmAvrg(Kernel* owner, uint seqNum, bool enable, bool enableDump):
WaveLimiter(owner, seqNum, enable, enableDump) {
measure_.resize(MaxWave + 1);
clear(measure_);
countAll_ = 0;
}
WLAlgorithmAvrg::~WLAlgorithmAvrg() {
}
void WLAlgorithmAvrg::outputTrace() {
if (!traceStream_.is_open()) {
return;
}
traceStream_ << "[WaveLimiter] " << owner_->name() << " state=" << state_
<< " currWaves=" << currWaves_ << " waves=" << waves_
<< " bestWave=" << bestWave_ << '\n';
output(traceStream_, "\n measure = ", measure_);
traceStream_ << "\n\n";
}
void WLAlgorithmAvrg::callback(ulong duration) {
dumper_.addData(duration, currWaves_, static_cast<char>(state_));
if (!enable_) {
return;
}
countAll_++;
switch (state_) {
case WARMUP:
state_ = ADAPT;
case ADAPT:
measure_[waves_] += duration;
if (countAll_ <= MaxWave * 5) {
waves_--;
if (waves_ == 0) {
waves_ = MaxWave;
}
}
else {
bestWave_ = MaxWave;
for (uint i=1; i<MaxWave; i++ ) {
if (measure_[i] < measure_[bestWave_]) {
bestWave_ = i;
}
}
waves_ = bestWave_;
state_ = RUN;
}
break;
case RUN:
default:
break;
}
}
WaveLimiterManager::WaveLimiterManager(Kernel* kernel):
owner_(kernel),
enable_(false),
enableDump_(!flagIsDefault(GPU_WAVE_LIMIT_DUMP)),
fixed_(GPU_WAVES_PER_SIMD) {
enableDump_(!flagIsDefault(GPU_WAVE_LIMIT_DUMP)) {
auto gpuDev = static_cast<const Device*>(&owner_->dev());
auto attrib = gpuDev->getAttribs();
auto hwInfo = gpuDev->hwInfo();
unsigned simdPerSH = 0;
setIfNotDefault(simdPerSH, GPU_WAVE_LIMIT_CU_PER_SH,
attrib.numberOfCUsperShaderArray * hwInfo->simdPerCU_);
fixed_ = GPU_WAVES_PER_SIMD * simdPerSH;
}
WaveLimiterManager::~WaveLimiterManager() {
@@ -248,7 +326,7 @@ amd::ProfilingCallback* WaveLimiterManager::getProfilingCallback(
return loc->second;
}
auto limiter = new WaveLimiter(owner_, limiters_.size(), enable_,
auto limiter = new WLAlgorithmSmooth(owner_, limiters_.size(), enable_,
enableDump_);
if (limiter == NULL) {
enable_ = false;
@@ -27,7 +27,7 @@ public:
//! Get waves per shader array to be used for kernel execution.
uint getWavesPerSH();
private:
protected:
enum StateKind {
WARMUP, ADAPT, RUN
};
@@ -51,42 +51,26 @@ private:
};
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
uint waves_; // Waves per SIMD to be set
uint bestWave_; // Optimal waves per SIMD
uint countAll_; // Number of kernel executions
uint dynRunCount_;
StateKind state_;
Kernel *owner_;
DataDumper dumper_;
std::ofstream traceStream_;
uint currWaves_; // Current waves per SIMD
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
//! Call back from Event::recordProfilingInfo to get execution time.
virtual void callback(ulong duration);
//! Update measurement data and optimal waves/simd with execution time.
void updateData(ulong time);
virtual void callback(ulong duration)=0;
//! Output trace of measurement/adaptation.
void outputTrace();
//! Clear measurement data for the next adaptation.
void clearData();
virtual void outputTrace()=0;
template<class T> void clear(T& A) {
for (auto &I : A) {
@@ -102,6 +86,47 @@ private:
}
};
class WLAlgorithmSmooth: public WaveLimiter {
public:
explicit WLAlgorithmSmooth(Kernel* owner, uint seqNum, bool enable, bool enableDump);
virtual ~WLAlgorithmSmooth();
private:
std::vector<ulong> reference_;
std::vector<ulong> trial_;
std::vector<ulong> ratio_;
bool discontinuous_; // Measured data is discontinuous
uint dynRunCount_;
uint dataCount_;
static uint AdaptCount; // Number of kernel executions for adapting
static uint AbandonThresh; // Threshold to abandon adaptation
static uint DscThresh; // Threshold for identifying discontinuities
//! Update measurement data and optimal waves/simd with execution time.
void updateData(ulong time);
//! Clear measurement data for the next adaptation.
void clearData();
//! Call back from Event::recordProfilingInfo to get execution time.
void callback(ulong duration);
//! Output trace of measurement/adaptation.
void outputTrace();
};
class WLAlgorithmAvrg: public WaveLimiter {
public:
explicit WLAlgorithmAvrg(Kernel* owner, uint seqNum, bool enable, bool enableDump);
virtual ~WLAlgorithmAvrg();
private:
//! Call back from Event::recordProfilingInfo to get execution time.
void callback(ulong duration);
//! Output trace of measurement/adaptation.
void outputTrace();
};
// Create wave limiter for each virtual device for a kernel and manages the wave limiters.
class WaveLimiterManager {
public: