diff --git a/InterleavingTest.cpp b/InterleavingTest.cpp index 7e005fe..035a700 100644 --- a/InterleavingTest.cpp +++ b/InterleavingTest.cpp @@ -8,10 +8,10 @@ struct Job { int *input; + bool (*next)(Job *); }; -bool stepJob(void *x) { - auto *j = (Job *)x; +bool stepJob(Job *j) { auto &val = *j->input; auto result = --val == 0; #ifdef __x86_64__ @@ -23,17 +23,24 @@ bool stepJob(void *x) { // So we can look at the disassembly more easily extern "C" { -void sequential(void **jobs, bool (*step)(void *), int count) { +void sequential(Job **jobs, int count) { for (int i = 0; i < count; ++i) { - while (!step(jobs[i])) + while (!jobs[i]->next(jobs[i])) ; } } -void interleaveSwapping(void **jobs, bool (*step)(void *), int remaining) { +void sequentialNoFuncPtr(Job **jobs, int count) { + for (int i = 0; i < count; ++i) { + while (!stepJob(jobs[i])) + ; + } +} + +void interleaveSwapping(Job **jobs, int remaining) { int current = 0; while (remaining > 0) { - bool done = step(jobs[current]); + bool done = jobs[current]->next(jobs[current]); if (done) { jobs[current] = jobs[remaining - 1]; --remaining; @@ -46,13 +53,13 @@ void interleaveSwapping(void **jobs, bool (*step)(void *), int remaining) { } } -void interleaveBoundedCyclicList(void **jobs, bool (*step)(void *), int count) { +void interleaveBoundedCyclicList(Job **jobs, int count) { if (count == 0) { return; } constexpr int kConcurrent = 32; - void *inProgress[kConcurrent]; + Job *inProgress[kConcurrent]; int nextJob[kConcurrent]; int started = std::min(kConcurrent, count); @@ -65,7 +72,7 @@ void interleaveBoundedCyclicList(void **jobs, bool (*step)(void *), int count) { int prevJob = started - 1; int job = 0; for (;;) { - bool done = step(inProgress[job]); + bool done = inProgress[job]->next(inProgress[job]); if (done) { if (started == count) { if (prevJob == job) @@ -82,7 +89,7 @@ void interleaveBoundedCyclicList(void **jobs, bool (*step)(void *), int count) { } } -void interleaveCyclicList(void **jobs, bool (*step)(void *), int count) { +void interleaveCyclicList(Job **jobs, int count) { auto *nextJob = (int *)alloca(sizeof(int) * count); for (int i = 0; i < count - 1; ++i) { @@ -93,7 +100,7 @@ void interleaveCyclicList(void **jobs, bool (*step)(void *), int count) { int prevJob = count - 1; int job = 0; for (;;) { - bool done = step(jobs[job]); + bool done = jobs[job]->next(jobs[job]); if (done) { if (prevJob == job) break; @@ -119,12 +126,14 @@ int main() { for (int i = 0; i < kNumJobs; ++i) { originalInput[i] = rand() % 5 + 3; jobs[i].input = new int{originalInput[i]}; + jobs[i].next = stepJob; iters += *jobs[i].input; } bench.batch(iters); for (auto [scheduler, name] : - {std::make_pair(sequential, "sequential"), + {std::make_pair(sequentialNoFuncPtr, "sequentialNoFuncPtr"), + std::make_pair(sequential, "sequential"), std::make_pair(interleaveSwapping, "interleavingSwapping"), std::make_pair(interleaveBoundedCyclicList, "interleaveBoundedCyclicList"), @@ -133,11 +142,11 @@ int main() { *jobs[i].input = originalInput[i]; } memcpy(jobsCopy, jobs, sizeof(jobs)); - void *ps[kNumJobs]; + Job *ps[kNumJobs]; for (int i = 0; i < kNumJobs; ++i) { ps[i] = jobsCopy + i; } - scheduler(ps, stepJob, kNumJobs); + scheduler(ps, kNumJobs); for (int i = 0; i < kNumJobs; ++i) { if (*jobsCopy[i].input != 0) { fprintf(stderr, "%s failed\n", name); @@ -150,11 +159,11 @@ int main() { *jobs[i].input = originalInput[i]; } memcpy(jobsCopy, jobs, sizeof(jobs)); - void *ps[kNumJobs]; + Job *ps[kNumJobs]; for (int i = 0; i < kNumJobs; ++i) { ps[i] = jobsCopy + i; } - scheduler(ps, stepJob, kNumJobs); + scheduler(ps, kNumJobs); }); } for (int i = 0; i < kNumJobs; ++i) {