Skip to content
Snippets Groups Projects
Commit 36191465 authored by Florian Schmaus's avatar Florian Schmaus
Browse files

Add Locality eval

parent 3a80a841
No related branches found
No related tags found
No related merge requests found
......@@ -3,3 +3,6 @@ target_link_libraries(time_to_spawn Threads::Threads emper)
add_executable(spawn_a_lot SpawnALot.cpp)
target_link_libraries(spawn_a_lot Threads::Threads emper)
add_executable(locality Locality.cpp)
target_link_libraries(locality Threads::Threads emper)
#include "Fiber.hpp"
#include "Runtime.hpp"
#include "PrivateSemaphore.hpp"
#include "CountingPrivateSemaphore.hpp"
#include "LawsStrategy.hpp"
#include "DebugUtil.hpp"
#include <algorithm>
#include <random>
#include <cstdint>
#include <thread>
#define L1_CACHE_LINE_SIZE 64 // 64 Bytes
#define L1_DCACHE_SIZE (32*1024) // 32 KiB
#define L2_DCACHE_SIZE (256*1024) // 256 KiB
#define L3_DCACHE_SIZE (4096*1024) // 4 MiB
static std::uniform_int_distribution<> UINT8_UNIFORM_DISTRIBUTION(0, UINT8_MAX);
struct State {
const unsigned int fiberCount;
const unsigned int bytesPerFiber;
const unsigned int rounds;
Runtime& runtime;
std::mt19937 randomGenerator;
// TODO: Should the affinities in the affinity array be cache line
// aligned to avoid false sharing?
workeraffinity_t* affinity;
uint8_t* data;
State(Runtime& runtime,
unsigned int fiberCount,
unsigned int bytesPerFiber,
unsigned int rounds,
unsigned int seed) :
fiberCount(fiberCount) ,
bytesPerFiber(bytesPerFiber) ,
rounds(rounds) ,
runtime(runtime) {
randomGenerator = std::mt19937(seed);
affinity = new workeraffinity_t[fiberCount]();
data = new uint8_t[fiberCount * bytesPerFiber];
std::generate(data, data + fiberCount, [this] { return getNextRandom(); });
}
~State() {
delete [] affinity;
delete [] data;
}
uint8_t getNextRandom() {
return UINT8_UNIFORM_DISTRIBUTION(randomGenerator);
}
};
struct FiberArgs {
uint8_t* fiberData;
uint8_t roundData;
PS* ps;
// TODO: Check if this member is still needed
State* state;
};
static void performRound(State& state) {
uint8_t roundData = state.getNextRandom();
CPS cps(state.fiberCount);
FiberArgs* fiberArgs = new FiberArgs[state.fiberCount];
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;
Fiber* fiber = Fiber::from([](void* fiberArgsPtr) {
FiberArgs* fiberArgs = (FiberArgs*) fiberArgsPtr;
uint8_t* fiberData = fiberArgs->fiberData;
unsigned int bytesPerFiber = fiberArgs->state->bytesPerFiber;
// 75% Chance that this fiber will do work.
if (fiberData[0] < 192) {
for (unsigned int i = 0; i < bytesPerFiber; i++) {
fiberData[i] += fiberArgs->roundData;
if (fiberData[i] < 128) {
fiberData[i] += fiberArgs->roundData / 2;
}
if (fiberData[i] > 192) {
fiberData[i] -= (fiberArgs->roundData * 4);
}
}
}
fiberArgs->ps->signal();
}, (void*) (fiberArgs + i), state.affinity + i);
state.runtime.schedule(*fiber);
}
cps.wait();
delete [] fiberArgs;
}
static void run(Runtime& runtime,
unsigned int fiberCount,
unsigned int bytesPerFiber,
unsigned int rounds,
unsigned int seed) {
runtime.executeAndWait([&] {
State state(runtime, fiberCount, bytesPerFiber, rounds, seed);
for (unsigned int i = 0; i < state.rounds; ++i) {
performRound(state);
}
});
}
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;
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;
}
{
using namespace std::chrono_literals;
std::cout << "Sleeping for 2s" << std::endl;
std::this_thread::sleep_for(2s);
std::cout << "Done sleeping" << std::endl;
}
{
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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment