From cc770a6f828e127688a6a9fe5063b3fe1b06cde4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus <flow@cs.fau.de> Date: Tue, 31 Jul 2018 13:19:27 +0200 Subject: [PATCH] eval/Locality: Started FIBER_METADATA and add argument parsing --- eval/Locality.cpp | 165 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 129 insertions(+), 36 deletions(-) diff --git a/eval/Locality.cpp b/eval/Locality.cpp index aabca56b..0d48302d 100644 --- a/eval/Locality.cpp +++ b/eval/Locality.cpp @@ -1,5 +1,6 @@ #include "Fiber.hpp" #include "Runtime.hpp" +#include "Dispatcher.hpp" #include "PrivateSemaphore.hpp" #include "CountingPrivateSemaphore.hpp" #include "LawsStrategy.hpp" @@ -9,6 +10,7 @@ #include <random> #include <cstdint> #include <thread> +#include <unistd.h> #define L1_CACHE_LINE_SIZE 64 // 64 Bytes @@ -16,8 +18,17 @@ #define L2_DCACHE_SIZE (256*1024) // 256 KiB #define L3_DCACHE_SIZE (4096*1024) // 4 MiB +//#define FIBER_METADATA + static std::uniform_int_distribution<> UINT8_UNIFORM_DISTRIBUTION(0, UINT8_MAX); +struct FiberMetadata { + workerid_t workerId; + workeraffinity_t currentAffinity; + std::chrono::time_point<std::chrono::high_resolution_clock> start; + std::chrono::time_point<std::chrono::high_resolution_clock> end; +}; + struct State { const unsigned int fiberCount; const unsigned int bytesPerFiber; @@ -29,6 +40,8 @@ struct State { // aligned to avoid false sharing? workeraffinity_t* affinity; uint8_t* data; + FiberMetadata* fiberMetadata; + //std::map<unsigned int, std::vector<FiberMetadata>> fiberMetadata; State(Runtime& runtime, unsigned int fiberCount, @@ -40,8 +53,14 @@ struct State { rounds(rounds) , runtime(runtime) { randomGenerator = std::mt19937(seed); - affinity = new workeraffinity_t[fiberCount](); + affinity = new workeraffinity_t[fiberCount]; + for (unsigned int i = 0; i < fiberCount; ++i) { + affinity[i] = Fiber::NOT_AFFINE; + } data = new uint8_t[fiberCount * bytesPerFiber]; +#ifdef FIBER_METADATA + fiberMetadata = new FiberMetadata[fiberCount * rounds]; +#endif std::generate(data, data + fiberCount, [this] { return getNextRandom(); }); } @@ -49,11 +68,18 @@ struct State { ~State() { delete [] affinity; delete [] data; +#ifdef FIBER_METADATA + delete [] fiberMetadata; +#endif } uint8_t getNextRandom() { return UINT8_UNIFORM_DISTRIBUTION(randomGenerator); } + + FiberMetadata* getFiberMetadata(unsigned int fiberNum, unsigned int roundNum) { + return fiberMetadata + (fiberNum * fiberCount) + roundNum; + } }; struct FiberArgs { @@ -62,24 +88,43 @@ struct FiberArgs { PS* ps; // TODO: Check if this member is still needed State* state; - +#ifdef FIBER_METADATA + FiberMetadata* fiberMetadata; +#endif }; -static void performRound(State& state) { +static void performRound(State& state, +#ifndef FIBER_METADATA + UNUSED_ARG +#endif + unsigned int round) { uint8_t roundData = state.getNextRandom(); CPS cps(state.fiberCount); FiberArgs* fiberArgs = new FiberArgs[state.fiberCount]; + DBG("Starting round " << round); + for (unsigned int i = 0; i < state.fiberCount; ++i) { fiberArgs[i].fiberData = state.data + (i * state.bytesPerFiber); fiberArgs[i].roundData = roundData; fiberArgs[i].ps = &cps; fiberArgs[i].state = &state; +#ifdef FIBER_METADATA + fiberArgs[i].fiberMetadata = state.getFiberMetadata(i, round); +#endif Fiber* fiber = Fiber::from([](void* fiberArgsPtr) { FiberArgs* fiberArgs = (FiberArgs*) fiberArgsPtr; +#ifdef FIBER_METADATA + FiberMetadata* fiberMetadata = fiberArgs->fiberMetadata; + + fiberMetadata->start = std::chrono::high_resolution_clock::now(); + fiberMetadata->workerId = Runtime::getWorkerId(); + fiberMetadata->currentAffinity = Dispatcher::getCurrentFiber().getAffinity(); +#endif + uint8_t* fiberData = fiberArgs->fiberData; unsigned int bytesPerFiber = fiberArgs->state->bytesPerFiber; // 75% Chance that this fiber will do work. @@ -95,6 +140,10 @@ static void performRound(State& state) { } } +#ifdef FIBER_METADATA + fiberMetadata->end = std::chrono::high_resolution_clock::now(); +#endif + fiberArgs->ps->signal(); }, (void*) (fiberArgs + i), state.affinity + i); @@ -103,9 +152,29 @@ static void performRound(State& state) { cps.wait(); + DBG("Finished round " << round); + delete [] fiberArgs; } +IGNORE_UNUSED_FUNCTION +static void printState(State& state) { + std::ostream& ostream = std::cout; + for (unsigned int fiberNum = 0; fiberNum < state.fiberCount; ++fiberNum) { + for (unsigned int roundNum = 0; roundNum < state.rounds; ++roundNum) { + FiberMetadata* fiberMetadata = state.getFiberMetadata(fiberNum, roundNum); + + ostream << fiberNum + << ", " << roundNum + << ", " << fiberMetadata->workerId + << ", " << fiberMetadata->currentAffinity + << ", " << fiberMetadata->start.time_since_epoch().count() + << ", " << fiberMetadata->end.time_since_epoch().count() + << std::endl; + } + } +} +POP_DIAGNOSTIC static void run(Runtime& runtime, unsigned int fiberCount, @@ -116,52 +185,76 @@ static void run(Runtime& runtime, runtime.executeAndWait([&] { State state(runtime, fiberCount, bytesPerFiber, rounds, seed); for (unsigned int i = 0; i < state.rounds; ++i) { - performRound(state); + performRound(state, i); } + + //printState(state); }); } +enum RuntimeVariant { + ws, + wslh, +}; + int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { enableStacktraceOnAborts(); - const unsigned int coreCount = 4; - const unsigned int bytesPerFiber = L1_DCACHE_SIZE / 4; - const unsigned int fiberCount = coreCount * 6; - const unsigned int rounds = 10; - const unsigned int seed = 42; + RuntimeVariant runtimeVariant = ws; + unsigned int rounds = 10; + unsigned int seed = 42; + + int opt; + while ((opt = getopt(argc, argv, "m:")) != -1) { + std::string optargString; + switch (opt) { + case 'm': + optargString = std::string(optarg); + if (optargString == "ws") { + runtimeVariant = ws; + } else if (optargString == "wslh") { + runtimeVariant = wslh; + } else { + std::cerr << "Invalid -m argument " << optargString << std::endl; + abort(); + } + break; + default: + abort(); + } + } + + unsigned int coreCount = 4; + unsigned int bytesPerFiber = L1_DCACHE_SIZE / 4; + unsigned int fiberCount = coreCount * 6; std::chrono::time_point<std::chrono::high_resolution_clock> start, end; std::chrono::microseconds diff; - { - Runtime runtime; - - start = std::chrono::high_resolution_clock::now(); - run(runtime, fiberCount, bytesPerFiber, rounds, seed); - end = std::chrono::high_resolution_clock::now(); - diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start); - std::cout << "W/o Locality: " - << diff.count() << " us" - << std::endl; + Runtime* runtime; + switch (runtimeVariant) { + case ws: + runtime = new Runtime(); break; + case wslh: + runtime = new Runtime(LawsStrategy::INSTANCE); break; } - { - using namespace std::chrono_literals; - std::cout << "Sleeping for 2s" << std::endl; - std::this_thread::sleep_for(2s); - std::cout << "Done sleeping" << std::endl; + start = std::chrono::high_resolution_clock::now(); + run(*runtime, fiberCount, bytesPerFiber, rounds, seed); + end = std::chrono::high_resolution_clock::now(); + diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start); + + std::string variantName; + switch (runtimeVariant) { + case ws: + variantName = "W/o Locality: "; break; + case wslh: + variantName = "W Locality: "; break; } - { - RuntimeStrategy& lawsStrategy = LawsStrategy::INSTANCE; - Runtime runtime(lawsStrategy); - - start = std::chrono::high_resolution_clock::now(); - run(runtime, fiberCount, bytesPerFiber, rounds, seed); - end = std::chrono::high_resolution_clock::now(); - diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start); - std::cout << "W Locality: " - << diff.count() << " us" - << std::endl; - } + std::cout << variantName + << diff.count() << " us" + << std::endl; + + exit(EXIT_SUCCESS); } -- GitLab