Commit 5720c0d8 authored by Florian Fischer's avatar Florian Fischer
Browse files

add additional mode of introducing work

The default is Burst mode which inserts new work as fast as possible
sleeping until the next pulse.
Even mode distributes the new work evenly in the duration between two
pulses.
parent be5df101
Pipeline #81322 passed with stages
in 22 minutes and 6 seconds
......@@ -9,6 +9,7 @@
#include <exception>
#include <fstream> // IWYU pragma: keep
#include <iostream>
#include <sstream>
#include <string>
#include "CountingPrivateSemaphore.hpp"
......@@ -22,6 +23,39 @@ namespace po = boost::program_options;
using Clock = std::chrono::high_resolution_clock;
using TimePoint = std::chrono::time_point<Clock>;
enum class PulseMode {
Burst, /*!< Introduce all work as fast as possible */
Even, /*!< Introduce work evenly during the pulse */
};
auto operator<<(std::ostream& out, const PulseMode& mode) -> std::ostream& {
switch (mode) {
case PulseMode::Burst:
out << "burst";
break;
case PulseMode::Even:
out << "even";
break;
}
return out;
}
auto operator>>(std::istream& in, PulseMode& mode) -> std::istream& {
std::string token;
in >> token;
if (token == "burst") {
mode = PulseMode::Burst;
} else if (token == "even") {
mode = PulseMode::Even;
} else {
in.setstate(std::ios_base::failbit);
}
return in;
}
static PulseMode pulseMode;
// Pulse of new work in microseconds
static int64_t pulse = 1L * 1000 * 1000;
// Number of pulses
......@@ -62,18 +96,25 @@ static void pulser(Runtime& runtime) {
const workerid_t workerCount = runtime.getWorkerCount();
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);
}
// TODO: better calculate the time until the next pulse
struct timespec ts {
.tv_sec = 0, .tv_nsec = pulse * 1000
};
emper::nanosleep(&ts);
// TODO: Think about busy looping for small times
if (pulseMode == PulseMode::Burst) emper::nanosleep(&ts);
}
cps.wait();
runtime.initiateTermination();
......@@ -134,6 +175,7 @@ auto main(int argc, char* argv[]) -> int {
("utilization", po::value<unsigned>(&utilization)->default_value(utilization),
"The target utilization of the runtime")
("latencies-file", po::value<std::string>(), "File to store all collected latencies")
("pulse-mode", po::value<PulseMode>(&pulseMode)->default_value(PulseMode::Burst), "How to introducing the work")
;
// clang-format on
......
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