Merge pull request #2549 from ajbeamon/slow-task-and-priority-tracking-improvements

Slow task and priority tracker improvements
This commit is contained in:
Evan Tschannen 2020-04-14 13:26:32 -07:00 committed by GitHub
commit cf01233f28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 33 deletions

View File

@ -171,7 +171,7 @@ public:
INetworkConnections *network; // initially this, but can be changed
int64_t tsc_begin, tsc_end;
int64_t tscBegin, tscEnd;
double taskBegin;
TaskPriority currentTaskID;
uint64_t tasksIssued;
@ -195,7 +195,7 @@ public:
std::priority_queue<DelayedTask, std::vector<DelayedTask>> timers;
void checkForSlowTask(int64_t tscBegin, int64_t tscEnd, double duration, TaskPriority priority);
bool check_yield(TaskPriority taskId, bool isRunLoop);
bool check_yield(TaskPriority taskId, int64_t tscNow);
void processThreadReady();
void trackMinPriority( TaskPriority minTaskID, double now );
void stopImmediately() {
@ -863,7 +863,7 @@ Net2::Net2(const TLSConfig& tlsConfig, bool useThreadPool, bool useMetrics)
stopped(false),
tasksIssued(0),
// Until run() is called, yield() will always yield
tsc_begin(0), tsc_end(0), taskBegin(0), currentTaskID(TaskPriority::DefaultYield),
tscBegin(0), tscEnd(0), taskBegin(0), currentTaskID(TaskPriority::DefaultYield),
lastMinTaskID(TaskPriority::Zero),
numYields(0),
tlsInitialized(false),
@ -1047,13 +1047,14 @@ void Net2::run() {
++countRunLoop;
if (runFunc) {
tsc_begin = __rdtsc();
tscBegin = __rdtsc();
taskBegin = nnow;
trackMinPriority(TaskPriority::RunCycleFunction, taskBegin);
runFunc();
double taskEnd = timer_monotonic();
trackMinPriority(TaskPriority::RunLoop, taskEnd);
countLaunchTime += taskEnd - taskBegin;
checkForSlowTask(tsc_begin, __rdtsc(), taskEnd - taskBegin, TaskPriority::RunCycleFunction);
checkForSlowTask(tscBegin, __rdtsc(), taskEnd - taskBegin, TaskPriority::RunCycleFunction);
}
double sleepTime = 0;
@ -1078,16 +1079,17 @@ void Net2::run() {
}
}
tsc_begin = __rdtsc();
tscBegin = __rdtsc();
taskBegin = timer_monotonic();
trackMinPriority(TaskPriority::ASIOReactor, taskBegin);
reactor.react();
updateNow();
double now = this->currentTime;
trackMinPriority(TaskPriority::RunLoop, now);
countReactTime += now - taskBegin;
checkForSlowTask(tsc_begin, __rdtsc(), now - taskBegin, TaskPriority::ASIOReactor);
checkForSlowTask(tscBegin, __rdtsc(), now - taskBegin, TaskPriority::ASIOReactor);
if ((now-nnow) > FLOW_KNOBS->SLOW_LOOP_CUTOFF && nondeterministicRandom()->random01() < (now-nnow)*FLOW_KNOBS->SLOW_LOOP_SAMPLING_RATE)
TraceEvent("SomewhatSlowRunLoopTop").detail("Elapsed", now - nnow);
@ -1104,8 +1106,8 @@ void Net2::run() {
processThreadReady();
tsc_begin = __rdtsc();
tsc_end = tsc_begin + FLOW_KNOBS->TSC_YIELD_TIME;
tscBegin = __rdtsc();
tscEnd = tscBegin + FLOW_KNOBS->TSC_YIELD_TIME;
taskBegin = timer_monotonic();
numYields = 0;
TaskPriority minTaskID = TaskPriority::Max;
@ -1115,8 +1117,11 @@ void Net2::run() {
while (!ready.empty()) {
++countTasks;
currentTaskID = ready.top().taskID;
if(currentTaskID < minTaskID) {
trackMinPriority(currentTaskID, taskBegin);
minTaskID = currentTaskID;
}
priorityMetric = static_cast<int64_t>(currentTaskID);
minTaskID = std::min(minTaskID, currentTaskID);
Task* task = ready.top().task;
ready.pop();
@ -1128,17 +1133,24 @@ void Net2::run() {
TraceEvent(SevError, "TaskError").error(unknown_error());
}
if (check_yield(TaskPriority::Max, true)) {
double tscNow = __rdtsc();
double newTaskBegin = timer_monotonic();
if (check_yield(TaskPriority::Max, tscNow)) {
checkForSlowTask(tscBegin, tscNow, newTaskBegin - taskBegin, currentTaskID);
FDB_TRACE_PROBE(run_loop_yield);
++countYields;
break;
break;
}
taskBegin = newTaskBegin;
tscBegin = tscNow;
}
trackMinPriority(TaskPriority::RunLoop, taskBegin);
queueSize = ready.size();
FDB_TRACE_PROBE(run_loop_done, queueSize);
trackMinPriority(minTaskID, now);
#if defined(__linux__)
if(FLOW_KNOBS->SLOWTASK_PROFILING_INTERVAL > 0) {
sigset_t orig_set;
@ -1250,12 +1262,8 @@ void Net2::checkForSlowTask(int64_t tscBegin, int64_t tscEnd, double duration, T
}
}
bool Net2::check_yield( TaskPriority taskID, bool isRunLoop ) {
if(!isRunLoop && numYields > 0) {
++numYields;
return true;
}
bool Net2::check_yield( TaskPriority taskID, int64_t tscNow ) {
// SOMEDAY: Yield if there are lots of higher priority tasks queued?
if ((g_stackYieldLimit) && ( (intptr_t)&taskID < g_stackYieldLimit )) {
++countYieldBigStack;
return true;
@ -1268,35 +1276,31 @@ bool Net2::check_yield( TaskPriority taskID, bool isRunLoop ) {
return true;
}
// SOMEDAY: Yield if there are lots of higher priority tasks queued?
int64_t tsc_now = __rdtsc();
double newTaskBegin = timer_monotonic();
if (tsc_now < tsc_begin) {
if (tscNow < tscBegin) {
return true;
}
if(isRunLoop) {
checkForSlowTask(tsc_begin, tsc_now, newTaskBegin-taskBegin, currentTaskID);
}
if (tsc_now > tsc_end) {
if (tscNow > tscEnd) {
++numYields;
return true;
}
taskBegin = newTaskBegin;
tsc_begin = tsc_now;
return false;
}
bool Net2::check_yield( TaskPriority taskID ) {
return check_yield(taskID, false);
if(numYields > 0) {
++numYields;
return true;
}
return check_yield(taskID, __rdtsc());
}
Future<class Void> Net2::yield( TaskPriority taskID ) {
++countYieldCalls;
if (taskID == TaskPriority::DefaultYield) taskID = currentTaskID;
if (check_yield(taskID, false)) {
if (check_yield(taskID)) {
++countYieldCallsTrue;
return delay(0, taskID);
}

View File

@ -35,6 +35,7 @@
enum class TaskPriority {
Max = 1000000,
RunLoop = 30000,
ASIOReactor = 20001,
RunCycleFunction = 20000,
FlushTrace = 10500,