Skip to content
Snippets Groups Projects
Commit 5b7a6b75 authored by Nicolas Pfeiffer's avatar Nicolas Pfeiffer
Browse files

started to add fibril benchmarks and adjust them to use emper

parent 3961d7fe
No related branches found
No related tags found
No related merge requests found
...@@ -114,6 +114,8 @@ add_subdirectory("apps") ...@@ -114,6 +114,8 @@ add_subdirectory("apps")
add_subdirectory("tests") add_subdirectory("tests")
add_subdirectory("benchmarks")
add_subdirectory("eval") add_subdirectory("eval")
file(GLOB ALL_SOURCE_FILES *.cpp) file(GLOB ALL_SOURCE_FILES *.cpp)
......
#add_executable(fib fib.c)
#target_link_libraries(fib c_emper)
#add_test(fib fib)
add_executable(fib fib.cpp)
target_link_libraries(fib Threads::Threads emper)
add_test(fib fib)
#include <stdio.h>
#include "test.h"
int n = 42;
int m;
static int fib_fast(int n)
{
if (n < 2) return n;
int i = 2, x = 0, y = 0, z = 1;
do {
x = y;
y = z;
z = x + y;
} while (i++ < n);
return z;
}
fibril int fib(int n)
{
if (n < 2) return n;
int x, y;
fibril_t fr;
fibril_init(&fr);
fibril_fork(&fr, &x, fib, (n - 1));
y = fib(n - 2);
fibril_join(&fr);
return x + y;
}
int verify()
{
int expect = fib_fast(n);
if (expect != m) {
printf("fib(%d)=%d (expected %d)\n", n, m, expect);
return 1;
}
return 0;
}
void init() {}
void prep() {}
void test() {
m = fib(n);
}
#ifndef FIBRIL_H
#define FIBRIL_H
#define FIBRIL_SUCCESS 0
#define FIBRIL_FAILURE -1
/**
* These are special arguments to fibril_rt_init().
* FIBRIL_NPROCS tells the runtime to fetch the number of processors
* from the environment variable FIBRIL_NPROCS (getenv(FIBRIL_NPROCS)).
* FIBRIL_NPROCS_ONLN tells the runtime to use all available processors
* in the system (sysconf(_SC_NPROCESSORS_ONLN)).
*/
#define FIBRIL_NPROCS 0
#define FIBRIL_NPROCS_ONLN -1
#include "fibril_emper.h"
#if 0
/** Serial version. */
#ifdef FIBRIL_SERIAL
#include <fibril/serial.h>
/** Cilkplus version. */
#elif FIBRIL_CILKPLUS
#include <fibril/cilkplus.h>
/** TBB version. */
#elif FIBRIL_TBB
#include <fibril/tbb.h>
/** Fibril version. */
#else
#include <fibril/fibrile.h>
#endif
#endif
/** fibril_fork has two versions: one with return value and one without. */
#define fibril_fork(...) _fibril_fork_(_fibril_nth(__VA_ARGS__), __VA_ARGS__)
#define _fibril_fork_(n, ...) _fibril_concat(_fibril_fork_, n)(__VA_ARGS__)
/** If nargs is 3, use the no-return-value version. */
#define _fibril_fork_3(...) fibril_fork_nrt(__VA_ARGS__)
/** If nargs is 4, use the with-return-value version. */
#define _fibril_fork_4(...) fibril_fork_wrt(__VA_ARGS__)
/** Helper macros to count number of arguments. */
#define _fibril_nth(...) _fibril_nth_(__VA_ARGS__, ## __VA_ARGS__, \
16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, \
8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 0)
#define _fibril_nth_(_1, _1_, _2, _2_, _3, _3_, _4, _4_, _5, _5_, \
_6, _6_, _7, _7_, _8, _8_, _9, _9_, _10, _10_, _11, _11_, _12, _12_, \
_13, _13_, _14, _14_, _15, _15_, _16, _16_, N, ...) N
#define _fibril_concat(left, right) left##right
#endif /* end of include guard: FIBRIL_H */
#ifndef FIBRIL_EMPER_H
#define FIBRIL_EMPER_H
#include "emper.hpp"
class StackFibril {
private:
char memory[sizeof(Fibril)];
Fibril *f;
public:
__attribute__((always_inline))
StackFibril() {
f = new (memory) Fibril();
}
~StackFibril() {
f->~Fibril();
}
Fibril* operator->() const noexcept {
return f;
}
Fibril& operator*() const {
return *f;
}
};
#define fibril_t StackFibril
#define fibril_init(fp)
#define fibril_join(fp) (*fp)->join();
#define fibril_fork_nrt(fp, fn, ag) (*fp)->fork([=] () {fn(ag); })
#define fibril_fork_wrt(fp, rt, fn, ag) do { \
__typeof__(rt) rtp = rt; \
(*fp)->fork([=] () { *rtp = fn(ag); }); \
} while (0);
#define fibril_rt_init(n) Runtime runtime; runtime.executeAndWait([&] () {
#define fibril_rt_exit() });
#define fibril_rt_nprocs() runtime.getWorkerCount()
#endif /* end of include guard: CILKPLUS_H */
#ifndef TEST_H
#define TEST_H
#if HAVE_CONFIG_H
#include "config.h"
#endif
extern void init();
extern void prep();
extern void test();
extern int verify();
extern int n;
#include <stdlib.h>
#include "fibril.h"
#ifdef BENCHMARK
#include <stdio.h>
#include <float.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
static void sort(float * a, int n)
{
int i, sorted = 0;
while (!sorted) {
sorted = 1;
for (i = 1; i < n; ++i) {
if (a[i] < a[i - 1]) {
float t = a[i];
a[i] = a[i - 1];
a[i - 1] = t;
sorted = 0;
}
}
}
}
size_t static inline time_elapsed(size_t val)
{
struct timeval t;
gettimeofday(&t, NULL);
return t.tv_sec * 1000000 + t.tv_usec - val;
}
static void bench(const char * name, int nprocs)
{
static int iter = 10;
float times[iter];
printf("===========================================\n");
printf(" Benchmark: %s\n", strrchr(name, '/') + 1);
printf(" Input size: %d\n", n);
printf(" Number of iterations: %d\n", iter);
printf(" Number of processors: %d\n", nprocs);
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
long rss = ru.ru_maxrss;
long flt = ru.ru_minflt;
int i;
for (i = 0; i < iter; ++i) {
prep();
size_t usecs = time_elapsed(0);
test();
usecs = time_elapsed(usecs);
times[i] = usecs / 1000000.0;
printf(" #%d execution time: %f s\n", i, times[i]);
}
sort(times, iter);
float p10 = times[1];
float p90 = times[8];
float med = times[5];
getrusage(RUSAGE_SELF, &ru);
rss = ru.ru_maxrss - rss;
flt = ru.ru_minflt - flt;
printf(" Execution time summary:\n");
printf(" Median: %f s\n", med);
printf(" 10th %%: %f s\n", p10);
printf(" 90th %%: %f s\n", p90);
printf(" Resources summary: \n");
printf(" Max RSS: %ld (KB)\n", ru.ru_maxrss);
printf(" Runtime RSS: %ld (KB)\n", rss);
printf(" # of page faults: %ld\n", flt);
}
#endif
#include <stdlib.h>
int main(int argc, const char * argv[])
{
if (argc > 1 && (argc = atoi(argv[1])) > 0) {
n = argc;
}
init();
fibril_rt_init(0);
int nprocs = fibril_rt_nprocs();
#ifdef BENCHMARK
bench(argv[0], nprocs);
#else
(void) nprocs;
prep();
test();
#endif
fibril_rt_exit();
#ifdef BENCHMARK
#ifdef FIBRIL_STATS
printf(" Statistics summary:\n");
printf(" # of steals: %s\n", getenv("FIBRIL_N_STEALS"));
printf(" # of suspensions: %s\n", getenv("FIBRIL_N_SUSPENSIONS"));
printf(" # of stacks used: %s\n", getenv("FIBRIL_N_STACKS"));
printf(" # of pages used: %s\n", getenv("FIBRIL_N_PAGES"));
#endif
printf("===========================================\n");
#endif
return verify();
}
#endif /* end of include guard: TEST_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment