Skip to content

Commit

Permalink
Clarify predictor behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
jim90247 committed Apr 26, 2020
1 parent c9684d0 commit cf19941
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 33 deletions.
22 changes: 12 additions & 10 deletions src/hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,18 +358,17 @@ double estimate_full_burst(double measured_burst, double measured_window) {

/**
* send token request to scheduling system
* @param pred_full_burst predicted kernel burst (milliseconds)
* @param pred_window predicted window period (milliseconds)
* @param next_burst predicted kernel burst (milliseconds)
* @return received time quota (milliseconds)
*/
double get_token_from_scheduler(double pred_full_burst) {
double get_token_from_scheduler(double next_burst) {
char sbuf[REQ_MSG_LEN], rbuf[RSP_MSG_LEN], *attached;
size_t rpos = 0;
int rc;
double new_quota;

bzero(sbuf, REQ_MSG_LEN);
prepare_request(sbuf, REQ_QUOTA, overuse, pred_full_burst);
prepare_request(sbuf, REQ_QUOTA, overuse, next_burst);

// retrieve token from scheduler
rc = communicate(sbuf, rbuf, 0);
Expand Down Expand Up @@ -448,15 +447,18 @@ CUresult cuLaunchKernel_prehook(CUfunction f, unsigned int gridDimX, unsigned in
unsigned int blockDimY, unsigned int blockDimZ,
unsigned int sharedMemBytes, CUstream hStream, void **kernelParams,
void **extra) {
double new_quota, pred_full_burst;
double new_quota, next_burst;

window_predictor.record_stop();

// check if token expired
pthread_mutex_lock(&expiration_status_mutex);
if (us_since(request_start) / 1e3 + burst_predictor.predict_remain() >= quota_time) {
pred_full_burst =
estimate_full_burst(burst_predictor.predict_ctxfree(), window_predictor.predict_ctxfree());
// allow the kernel to launch if kernel burst already begins;
// otherwise, obtain a new token if this kernel burst may cause overuse
if (!burst_predictor.ongoing_unmerged() &&
us_since(request_start) / 1e3 + burst_predictor.predict_unmerged() >= quota_time) {
// estimate the duration of next kernel burst (merged)
next_burst =
estimate_full_burst(burst_predictor.predict_merged(), window_predictor.predict_merged());

// wait for all kernels finish
pthread_mutex_lock(&overuse_trk_mutex);
Expand All @@ -470,7 +472,7 @@ CUresult cuLaunchKernel_prehook(CUfunction f, unsigned int gridDimX, unsigned in
// interrupt the window which is started when overuse tracking completes
window_predictor.interrupt();

new_quota = get_token_from_scheduler(pred_full_burst);
new_quota = get_token_from_scheduler(next_burst);

// ensure predicted kernel burst is always less than quota
burst_predictor.set_upperbound(new_quota - 1.0);
Expand Down
41 changes: 20 additions & 21 deletions src/predictor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

/**
* Kernel burst and window period measurement/prediction utilities.
* There are two types of prediction result: plain (unmerged) and merged.
* Plain (unmerged) results are results of a single period/burst.
* Merged results are results of several consecutive periods/bursts.
*
* Measurement and prediction can be disabled by defining NO_PREDICT.
*/
Expand Down Expand Up @@ -70,14 +73,20 @@ Predictor::Predictor(const char *name, const double thres)

Predictor::~Predictor() { pthread_mutex_destroy(&mutex_); }

// Check whether we're in an active burst/period.
bool Predictor::ongoing_unmerged() { return period_begin_ != timepoint_t::max(); }

// Check whether we're in an active long-burst/long-period.
bool Predictor::ongoing_merged() { return long_period_begin_ != timepoint_t::max(); }

// Marks complete for a period
void Predictor::record_stop() {
#ifndef NO_PREDICT
double duration;
timepoint_t tp;

pthread_mutex_lock(&mutex_);
if (period_begin_ != timepoint_t::max()) {
if (ongoing_unmerged()) {
// record duration
tp = steady_clock::now();
duration = duration_cast<microseconds>(tp - period_begin_).count() / 1e3;
Expand All @@ -97,12 +106,12 @@ void Predictor::record_start() {
#ifndef NO_PREDICT
double intv;
pthread_mutex_lock(&mutex_);
if (period_begin_ == timepoint_t::max()) {
if (!ongoing_unmerged()) {
period_begin_ = steady_clock::now();

intv = duration_cast<microseconds>(period_begin_ - long_period_end_).count() / 1e3;
// long period did not started || last long period too long ago
if (long_period_begin_ == timepoint_t::max() || intv > MERGE_THRES) {
if (!ongoing_merged() || intv > MERGE_THRES) {
long_period_begin_ = period_begin_;
long_period_end_ = timepoint_t::min();
}
Expand All @@ -126,32 +135,22 @@ void Predictor::interrupt() {
#endif
}

// Get remaining time of current period.
double Predictor::predict_remain() {
double time_remain = 0;
// Get predicted length of an unmerged burst/period.
double Predictor::predict_unmerged() {
double pred = 0.0;
timepoint_t now;

#ifndef NO_PREDICT
pthread_mutex_lock(&mutex_);

now = steady_clock::now();

// update records
normal_records.drop_outdated(now);

time_remain = std::min(normal_records.get_max(), upperbound_);
if (period_begin_ != timepoint_t::max())
time_remain -= duration_cast<microseconds>(now - period_begin_).count() / 1e3;
if (time_remain < 0.0) time_remain = 0.0;

DEBUG("%s: period remain = %.3f", name_, time_remain);
normal_records.drop_outdated(steady_clock::now());
pred = normal_records.get_max();
pthread_mutex_unlock(&mutex_);
#endif
return time_remain;
return pred;
}

// Get the duration of a full period. Mini-period == Full period when no merge occurs.
double Predictor::predict_ctxfree() {
// Get predicted length of a (possibly) merged period.
double Predictor::predict_merged() {
double pred = 0.0;

#ifndef NO_PREDICT
Expand Down
6 changes: 4 additions & 2 deletions src/predictor.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ class Predictor {
void record_stop();
void record_start();
void interrupt();
double predict_remain();
double predict_ctxfree();
bool ongoing_unmerged();
bool ongoing_merged();
double predict_unmerged();
double predict_merged();
void set_upperbound(const double bound);
void reset();

Expand Down

0 comments on commit cf19941

Please sign in to comment.