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

Add Spawn-A-Lot eval

parent d4219586
No related branches found
No related tags found
No related merge requests found
add_executable(time_to_spawn TimeToSpawn.cpp) add_executable(time_to_spawn TimeToSpawn.cpp)
target_link_libraries(time_to_spawn Threads::Threads emper) 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)
#include "Runtime.hpp"
#include "PrivateSemaphore.hpp"
#include "BinaryPrivateSemaphore.hpp"
#include "CountingPrivateSemaphore.hpp"
#include "DebugUtil.hpp"
#define CACHE_LINE_SIZE 64
static void spawnALotThreadsRecursiveTFun(unsigned int depth, unsigned int width, unsigned int current_depth) {
if (current_depth == depth) return;
std::thread* threads = new std::thread[width];
const unsigned int new_depth = current_depth + 1;
for (unsigned int i = 0; i < width; ++i) {
threads[i] = std::thread(spawnALotThreadsRecursiveTFun, depth, width, new_depth);
}
for (unsigned int i = 0; i < width; ++i) {
threads[i].join();
}
delete[] threads;
}
static void spawnALotThreadsRecursive(unsigned int depth, unsigned int width) {
std::thread thread(spawnALotThreadsRecursiveTFun, depth, width, 0);
thread.join();
}
static void spawnALotThreadsNonRecursive(uint64_t count) {
uint8_t* flags = new uint8_t[count * CACHE_LINE_SIZE];
std::thread* threads = new std::thread[count];
for (uint64_t i = 0; i < count; ++i) {
threads[i] = std::thread([&flags, i] {
flags[i * CACHE_LINE_SIZE] = 1;
});
}
for (uint64_t i = 0; i < count; ++i) {
threads[i].join();
}
delete[] flags;
delete[] threads;
}
struct SpawnALotFibersData {
Runtime& runtime;
const unsigned int depth;
const unsigned int width;
PS& ps;
unsigned int current_depth;
SpawnALotFibersData(SpawnALotFibersData* oldData, PS& ps)
: runtime(oldData->runtime)
, depth(oldData->depth)
, width(oldData->width)
, ps(ps)
, current_depth(oldData->current_depth + 1) {
}
SpawnALotFibersData(Runtime& runtime, unsigned int depth, unsigned int width, PS& ps)
: runtime(runtime)
, depth(depth)
, width(width)
, ps(ps)
, current_depth(0) {
}
};
static void spawnALotFibersRecursiveFFun(void* dataPtr) {
SpawnALotFibersData* data = (SpawnALotFibersData*) dataPtr;
if (data->current_depth < data->depth) {
CPS childSem(data->width);
SpawnALotFibersData newData(data, childSem);
for (unsigned int i = 0; i < data->width; ++i) {
Fiber* fiber = Fiber::from(spawnALotFibersRecursiveFFun, (void*) &newData);
data->runtime.schedule(*fiber);
}
childSem.wait();
}
data->ps.signal();
}
static void spawnALotFibersRecursive(Runtime& runtime, unsigned int depth, unsigned int width) {
BPS bps;
SpawnALotFibersData data(runtime, depth, width, bps);
Fiber* fiber = Fiber::from(spawnALotFibersRecursiveFFun, (void*) &data);
runtime.schedule(*fiber);
bps.wait();
}
static void spawnALotFibersNonRecursive(Runtime& runtime, uint64_t count) {
uint8_t* flags = new uint8_t[count * CACHE_LINE_SIZE];
CPS cps(count);
for (uint64_t i = 0; i < count; ++i) {
Fiber* fiber = Fiber::from([i, &cps, flags] {
flags[i * CACHE_LINE_SIZE] = 1;
cps.signal();
});
runtime.schedule(*fiber);
}
cps.wait();
delete[] flags;
}
int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) {
enableStacktraceOnAborts();
const uint64_t count = 1024;
const unsigned int depth = 10;
const unsigned int width = 2;
std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
std::chrono::nanoseconds diff;
start = std::chrono::high_resolution_clock::now();
spawnALotThreadsRecursive(depth, width);
end = std::chrono::high_resolution_clock::now();
diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start);
std::cout << "Spawn a lot of threads recursive (depth="
<< depth << ", width="
<< width << ") took "
<< diff.count() << "us"
<< std::endl;
start = std::chrono::high_resolution_clock::now();
spawnALotThreadsNonRecursive(count);
end = std::chrono::high_resolution_clock::now();
diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start);
std::cout << "Spawn a lot of threads non-recursive (count="
<< count << ") took "
<< diff.count() << "us"
<< std::endl;
Runtime runtime;
runtime.executeAndWait([&] {
start = std::chrono::high_resolution_clock::now();
spawnALotFibersRecursive(runtime, depth, width);
end = std::chrono::high_resolution_clock::now();
diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start);
std::cout << "Spawn a lot of fibers recursive (depth="
<< depth << ", width="
<< width << ") took "
<< diff.count() << "us"
<< std::endl;
start = std::chrono::high_resolution_clock::now();
spawnALotFibersNonRecursive(runtime, count);
end = std::chrono::high_resolution_clock::now();
diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start);
std::cout << "Spawn a lot of fibers non-recursive (count="
<< count << ") took "
<< diff.count() << "us"
<< std::endl;
});
return EXIT_SUCCESS;
}
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