Separate AsioReactor sleep and react into two different functions. Track slow tasks and time spent in react, track time spent in launch. Don't track react time at priority 0.

This commit is contained in:
A.J. Beamon 2019-08-28 14:35:48 -07:00
parent e0824f4915
commit fa6e45a852
7 changed files with 84 additions and 56 deletions

View File

@ -37,7 +37,8 @@ class ASIOReactor {
public:
explicit ASIOReactor(Net2*);
void sleepAndReact(double timeout);
void sleep(double timeout);
void react();
void wake();

View File

@ -209,6 +209,8 @@ public:
Int64MetricHandle countASIOEvents;
Int64MetricHandle countSlowTaskSignals;
Int64MetricHandle priorityMetric;
DoubleMetricHandle countLaunchTime;
DoubleMetricHandle countReactTime;
BoolMetricHandle awakeMetric;
EventMetricHandle<SlowTask> slowTaskMetric;
@ -545,6 +547,8 @@ void Net2::initMetrics() {
priorityMetric.init(LiteralStringRef("Net2.Priority"));
awakeMetric.init(LiteralStringRef("Net2.Awake"));
slowTaskMetric.init(LiteralStringRef("Net2.SlowTask"));
countLaunchTime.init(LiteralStringRef("Net2.CountLaunchTime"));
countReactTime.init(LiteralStringRef("Net2.CountReactTime"));
}
void Net2::run() {
@ -580,7 +584,9 @@ void Net2::run() {
taskBegin = nnow;
trackMinPriority(TaskPriority::RunCycleFunction, taskBegin);
runFunc();
checkForSlowTask(tsc_begin, __rdtsc(), timer_monotonic() - taskBegin, TaskPriority::RunCycleFunction);
double taskEnd = timer_monotonic();
countLaunchTime += taskEnd - taskBegin;
checkForSlowTask(tsc_begin, __rdtsc(), taskEnd - taskBegin, TaskPriority::RunCycleFunction);
}
double sleepTime = 0;
@ -596,18 +602,26 @@ void Net2::run() {
if (!timers.empty()) {
sleepTime = timers.top().at - sleepStart; // + 500e-6?
}
trackMinPriority(TaskPriority::Zero, sleepStart);
if (sleepTime > 0) {
trackMinPriority(TaskPriority::Zero, sleepStart);
awakeMetric = false;
priorityMetric = 0;
reactor.sleep(sleepTime);
awakeMetric = true;
}
}
awakeMetric = false;
if( sleepTime > 0 )
priorityMetric = 0;
reactor.sleepAndReact(sleepTime);
awakeMetric = true;
tsc_begin = __rdtsc();
taskBegin = timer_monotonic();
trackMinPriority(TaskPriority::ASIOReactor, taskBegin);
reactor.react();
updateNow();
double now = this->currentTime;
countReactTime += now - taskBegin;
checkForSlowTask(tsc_begin, __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);
@ -988,7 +1002,7 @@ ASIOReactor::ASIOReactor(Net2* net)
#endif
}
void ASIOReactor::sleepAndReact(double sleepTime) {
void ASIOReactor::sleep(double sleepTime) {
if (sleepTime > FLOW_KNOBS->BUSY_WAIT_THRESHOLD) {
if (FLOW_KNOBS->REACTOR_FLAGS & 4) {
#ifdef __linux
@ -1015,6 +1029,9 @@ void ASIOReactor::sleepAndReact(double sleepTime) {
if (!(FLOW_KNOBS->REACTOR_FLAGS & 8))
threadYield();
}
}
void ASIOReactor::react() {
while (ios.poll_one()) ++network->countASIOEvents; // Make this a task?
}

View File

@ -137,7 +137,9 @@ SystemStatistics customSystemMonitor(std::string eventName, StatisticsState *sta
.detail("WriteProbes", netData.countWriteProbes - statState->networkState.countWriteProbes)
.detail("PacketsRead", netData.countPacketsReceived - statState->networkState.countPacketsReceived)
.detail("PacketsGenerated", netData.countPacketsGenerated - statState->networkState.countPacketsGenerated)
.detail("WouldBlock", netData.countWouldBlock - statState->networkState.countWouldBlock);
.detail("WouldBlock", netData.countWouldBlock - statState->networkState.countWouldBlock)
.detail("LaunchTime", netData.countLaunchTime - statState->networkState.countLaunchTime)
.detail("ReactTime", netData.countReactTime - statState->networkState.countReactTime);
for (int i = 0; i<NetworkMetrics::SLOW_EVENT_BINS; i++) {
if (int c = g_network->networkMetrics.countSlowEvents[i] - statState->networkMetricsState.countSlowEvents[i]) {

View File

@ -80,53 +80,49 @@ struct NetworkData {
int64_t countConnEstablished;
int64_t countConnClosedWithError;
int64_t countConnClosedWithoutError;
double countLaunchTime;
double countReactTime;
void init() {
auto getValue = [] (StringRef name) -> int64_t {
Reference<Int64Metric> r = Int64Metric::getOrCreateInstance(name);
int64_t v = 0;
if(r)
v = r->getValue();
return v;
};
bytesSent = getValue(LiteralStringRef("Net2.BytesSent"));
countPacketsReceived = getValue(LiteralStringRef("Net2.CountPacketsReceived"));
countPacketsGenerated = getValue(LiteralStringRef("Net2.CountPacketsGenerated"));
bytesReceived = getValue(LiteralStringRef("Net2.BytesReceived"));
countWriteProbes = getValue(LiteralStringRef("Net2.CountWriteProbes"));
countReadProbes = getValue(LiteralStringRef("Net2.CountReadProbes"));
countReads = getValue(LiteralStringRef("Net2.CountReads"));
countWouldBlock = getValue(LiteralStringRef("Net2.CountWouldBlock"));
countWrites = getValue(LiteralStringRef("Net2.CountWrites"));
countRunLoop = getValue(LiteralStringRef("Net2.CountRunLoop"));
countCantSleep = getValue(LiteralStringRef("Net2.CountCantSleep"));
countWontSleep = getValue(LiteralStringRef("Net2.CountWontSleep"));
countTimers = getValue(LiteralStringRef("Net2.CountTimers"));
countTasks = getValue(LiteralStringRef("Net2.CountTasks"));
countYields = getValue(LiteralStringRef("Net2.CountYields"));
countYieldBigStack = getValue(LiteralStringRef("Net2.CountYieldBigStack"));
countYieldCalls = getValue(LiteralStringRef("Net2.CountYieldCalls"));
countASIOEvents = getValue(LiteralStringRef("Net2.CountASIOEvents"));
countYieldCallsTrue = getValue(LiteralStringRef("Net2.CountYieldCallsTrue"));
countSlowTaskSignals = getValue(LiteralStringRef("Net2.CountSlowTaskSignals"));
countConnEstablished = getValue(LiteralStringRef("Net2.CountConnEstablished"));
countConnClosedWithError = getValue(LiteralStringRef("Net2.CountConnClosedWithError"));
countConnClosedWithoutError = getValue(LiteralStringRef("Net2.CountConnClosedWithoutError"));
countFileLogicalWrites = getValue(LiteralStringRef("AsyncFile.CountLogicalWrites"));
countFileLogicalReads = getValue(LiteralStringRef("AsyncFile.CountLogicalReads"));
countAIOSubmit = getValue(LiteralStringRef("AsyncFile.CountAIOSubmit"));
countAIOCollect = getValue(LiteralStringRef("AsyncFile.CountAIOCollect"));
countFileCacheWrites = getValue(LiteralStringRef("AsyncFile.CountCacheWrites"));
countFileCacheReads = getValue(LiteralStringRef("AsyncFile.CountCacheReads"));
countFileCacheWritesBlocked = getValue(LiteralStringRef("AsyncFile.CountCacheWritesBlocked"));
countFileCacheReadsBlocked = getValue(LiteralStringRef("AsyncFile.CountCacheReadsBlocked"));
countFileCachePageReadsMerged = getValue(LiteralStringRef("AsyncFile.CountCachePageReadsMerged"));
countFileCacheFinds = getValue(LiteralStringRef("AsyncFile.CountCacheFinds"));
countFileCacheReadBytes = getValue(LiteralStringRef("AsyncFile.CountCacheReadBytes"));
countFilePageCacheHits = getValue(LiteralStringRef("AsyncFile.CountCachePageReadsHit"));
countFilePageCacheMisses = getValue(LiteralStringRef("AsyncFile.CountCachePageReadsMissed"));
countFilePageCacheEvictions = getValue(LiteralStringRef("EvictablePageCache.CacheEvictions"));
bytesSent = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.BytesSent"));
countPacketsReceived = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountPacketsReceived"));
countPacketsGenerated = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountPacketsGenerated"));
bytesReceived = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.BytesReceived"));
countWriteProbes = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountWriteProbes"));
countReadProbes = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountReadProbes"));
countReads = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountReads"));
countWouldBlock = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountWouldBlock"));
countWrites = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountWrites"));
countRunLoop = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountRunLoop"));
countCantSleep = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountCantSleep"));
countWontSleep = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountWontSleep"));
countTimers = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountTimers"));
countTasks = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountTasks"));
countYields = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountYields"));
countYieldBigStack = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountYieldBigStack"));
countYieldCalls = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountYieldCalls"));
countASIOEvents = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountASIOEvents"));
countYieldCallsTrue = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountYieldCallsTrue"));
countSlowTaskSignals = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountSlowTaskSignals"));
countConnEstablished = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountConnEstablished"));
countConnClosedWithError = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountConnClosedWithError"));
countConnClosedWithoutError = Int64Metric::getValueOrDefault(LiteralStringRef("Net2.CountConnClosedWithoutError"));
countLaunchTime = DoubleMetric::getValueOrDefault(LiteralStringRef("Net2.CountLaunchTime"));
countReactTime = DoubleMetric::getValueOrDefault(LiteralStringRef("Net2.CountReactTime"));
countFileLogicalWrites = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountLogicalWrites"));
countFileLogicalReads = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountLogicalReads"));
countAIOSubmit = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountAIOSubmit"));
countAIOCollect = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountAIOCollect"));
countFileCacheWrites = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCacheWrites"));
countFileCacheReads = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCacheReads"));
countFileCacheWritesBlocked = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCacheWritesBlocked"));
countFileCacheReadsBlocked = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCacheReadsBlocked"));
countFileCachePageReadsMerged = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCachePageReadsMerged"));
countFileCacheFinds = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCacheFinds"));
countFileCacheReadBytes = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCacheReadBytes"));
countFilePageCacheHits = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCachePageReadsHit"));
countFilePageCacheMisses = Int64Metric::getValueOrDefault(LiteralStringRef("AsyncFile.CountCachePageReadsMissed"));
countFilePageCacheEvictions = Int64Metric::getValueOrDefault(LiteralStringRef("EvictablePageCache.CacheEvictions"));
}
};

View File

@ -269,6 +269,14 @@ struct MetricUtil {
return m;
}
static ValueType getValueOrDefault(StringRef const& name, StringRef const& id = StringRef(), ValueType defaultValue = ValueType()) {
Reference<T> r = getOrCreateInstance(name, id);
if(r) {
return r->getValue();
}
return defaultValue;
}
// Lookup the T metric by name and return its value (or nullptr if it doesn't exist)
static T * lookupMetric(MetricNameRef const &name) {
auto it = T::metricMap().find(name);
@ -1319,6 +1327,7 @@ public:
};
typedef ContinuousMetric<int64_t> Int64Metric;
typedef ContinuousMetric<double> DoubleMetric;
typedef Int64Metric VersionMetric;
typedef ContinuousMetric<bool> BoolMetric;
typedef ContinuousMetric<Standalone<StringRef>> StringMetric;
@ -1406,6 +1415,7 @@ typedef MetricHandle<Int64Metric> Int64MetricHandle;
typedef MetricHandle<VersionMetric> VersionMetricHandle;
typedef MetricHandle<BoolMetric> BoolMetricHandle;
typedef MetricHandle<StringMetric> StringMetricHandle;
typedef MetricHandle<DoubleMetric> DoubleMetricHandle;
template <typename E>
using EventMetricHandle = MetricHandle<EventMetric<E>>;

View File

@ -23,6 +23,7 @@
const StringRef BaseEventMetric::metricType = LiteralStringRef("Event");
template<> const StringRef Int64Metric::metricType = LiteralStringRef("Int64");
template<> const StringRef DoubleMetric::metricType = LiteralStringRef("Double");
template<> const StringRef BoolMetric::metricType = LiteralStringRef("Bool");
template<> const StringRef StringMetric::metricType = LiteralStringRef("String");

View File

@ -32,6 +32,7 @@
enum class TaskPriority {
Max = 1000000,
ASIOReactor = 20001,
RunCycleFunction = 20000,
FlushTrace = 10500,
WriteSocket = 10000,