From 80393713913065a3b40a7beca6e62926b76cfc70 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Sun, 8 May 2022 15:05:54 +0200 Subject: [PATCH] pulse: busy loop when evenly introducing work When evenly introducing work the sleep continuation of the pulser fiber is possibly delayed due to the worker executing an introduced work items distorting the pulse. This distortion does not occure when the pulser busy loops between introducing work items. We do not count the busy looping worker running the pulser when calculating the work items to reach the target utilization. --- eval/Pulse.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/eval/Pulse.cpp b/eval/Pulse.cpp index d9d00fa7..8944118c 100644 --- a/eval/Pulse.cpp +++ b/eval/Pulse.cpp @@ -63,6 +63,13 @@ static unsigned iterations = 30; // Utilization of the runtime in percent static unsigned utilization = 80; +template +static void loopFor(Timeunit time) { + const auto deadline = Clock::now() + time; + while (Clock::now() < deadline) { + } +} + class Work { public: static Work** doneWork; @@ -75,10 +82,7 @@ class Work { Work() : start(Clock::now()) {} void run() { - const auto deadline = Clock::now() + std::chrono::microseconds(pulse); - while (Clock::now() < deadline) { - } - + loopFor(std::chrono::microseconds(pulse)); finish(); } @@ -93,28 +97,26 @@ Work** Work::doneWork; thread_local Work** Work::localDoneWork; static void pulser(Runtime& runtime) { - const workerid_t workerCount = runtime.getWorkerCount(); + const workerid_t workerCount = runtime.getWorkerCount() - (pulseMode == PulseMode::Even ? 1 : 0); + ; const workerid_t workItems = (workerCount * utilization) / 100; - struct timespec ts { - 0, 0 - }; - // TODO: better calculate the time until the next burst - if (pulseMode == PulseMode::Burst) - ts.tv_nsec = pulse * 1000; - else - ts.tv_nsec = (pulse * 1000) / workItems; - CPS cps; for (unsigned i = 0; i < iterations; ++i) { for (unsigned w = 0; w < workItems; ++w) { Work* work = new Work(); spawn([=] { work->run(); }, cps); - if (pulseMode == PulseMode::Even) emper::nanosleep(&ts); + if (pulseMode == PulseMode::Even) + loopFor(std::chrono::nanoseconds((pulse * 1000) / workItems)); } // TODO: Think about busy looping for small times - if (pulseMode == PulseMode::Burst) emper::nanosleep(&ts); + if (pulseMode == PulseMode::Burst) { + struct timespec ts { + .tv_sec = 0, .tv_nsec = pulse * 1000 + }; + emper::nanosleep(&ts); + } } cps.wait(); runtime.initiateTermination(); -- GitLab