Commit 80393713 authored by Florian Fischer's avatar Florian Fischer
Browse files

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.
parent a529012b
Pipeline #81601 passed with stages
in 25 minutes and 19 seconds
......@@ -63,6 +63,13 @@ static unsigned iterations = 30;
// Utilization of the runtime in percent
static unsigned utilization = 80;
template <class Timeunit>
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();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment