Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "emper.hpp"
#include "LawsStrategy.hpp"
#include "Fiber.hpp"
#include <random>
static const unsigned int ROUND_COUNT = 10;
static const unsigned int FIBER_LOOPS = 10;
static const unsigned int PAYLOAD_COUNT = 4096;
typedef struct ALIGN_TO_CACHE_LINE {
// 4096 * 8 byte (64 bit) = 32 KiB = L1 cache size of most systems
uint64_t payload[PAYLOAD_COUNT];
CPS* cps;
unsigned int fiberNum;
} FiberData;
typedef struct ALIGN_TO_CACHE_LINE {
workeraffinity_t affinity;
} AlignedWorkerAffinity;
static void fiberFun(void* voidFiberData) {
FiberData* fiberData = static_cast<FiberData*>(voidFiberData);
std::random_device randomDevice;
std::mt19937_64 randomGenerator(randomDevice());
std::uniform_int_distribution<unsigned long long> randomDistribution(0, UINT64_MAX);
for (unsigned int i = 0; i < FIBER_LOOPS; ++i) {
for (unsigned int j = 0; j < PAYLOAD_COUNT; ++j) {
unsigned long long r = randomDistribution(randomGenerator);
fiberData->payload[j] += r;
}
}
fiberData->cps->signalAndExit();
}
static void alphaFun() {
Runtime* runtime = Runtime::getRuntime();
const unsigned int FIBER_COUNT = runtime->getWorkerCount() + 3;
AlignedWorkerAffinity *affinities = new AlignedWorkerAffinity[FIBER_COUNT];
FiberData* fiberData = new FiberData[FIBER_COUNT];
for (unsigned int i = 0; i < FIBER_COUNT; ++i) {
FiberData& currentFiberData = fiberData[i];
memset(currentFiberData.payload, 0, sizeof(uint64_t) * PAYLOAD_COUNT);
currentFiberData.fiberNum = i;
currentFiberData.cps = nullptr;
affinities[i].affinity = Fiber::NOT_AFFINE;
}
for (unsigned int round = 0; round < ROUND_COUNT; ++round) {
CPS cps(FIBER_COUNT);
for (unsigned int i = 0; i < FIBER_COUNT; ++i) {
FiberData* myFiberData = &fiberData[i];
myFiberData->cps = &cps;
Fiber* fiber = Fiber::from(&fiberFun,
myFiberData,
&affinities[i].affinity);
runtime->schedule(*fiber);
}
cps.wait();
}
std::atomic<uint64_t> finalResult(0);
CPS cps(FIBER_COUNT);
for (unsigned int i = 0; i < FIBER_COUNT; ++i) {
FiberData* myFiberData = &fiberData[i];
myFiberData->cps = &cps;
Fiber* fiber = Fiber::from([myFiberData, &finalResult]() {
uint64_t mySum = 0;
for (unsigned int i = 0; i < PAYLOAD_COUNT; ++i) {
mySum += myFiberData->payload[i];
}
finalResult += mySum;
myFiberData->cps->signalAndExit();
},
&affinities[i].affinity);
runtime->schedule(*fiber);
}
free(fiberData);
free(affinities);
std::cerr << "Result: " << finalResult << std::endl;
exit(EXIT_SUCCESS);
}
int main(UNUSED_ARG int args, UNUSED_ARG char *argv[]) {
RuntimeStrategy& lawsStrategy = LawsStrategy::INSTANCE;
Runtime runtime(lawsStrategy);
Fiber* alphaFiber = Fiber::from(&alphaFun);
runtime.schedule(*alphaFiber);
runtime.waitUntilFinished();
return 0;
}