diff --git a/apps/sel4bench/src/signal.c b/apps/sel4bench/src/signal.c index 1a9d800f..9578d008 100644 --- a/apps/sel4bench/src/signal.c +++ b/apps/sel4bench/src/signal.c @@ -35,17 +35,16 @@ static json_t *signal_process(void *results) desc.stable = false; desc.overhead = result.min; -#if defined CONFIG_APP_SIGNAL_EARLYPROC result = process_result_early_proc(raw_results->lo_num, raw_results->lo_sum, raw_results->lo_sum2, - raw_results->lo_prio_results); -#else - result = process_result(N_RUNS, raw_results->lo_prio_results, desc); -#endif + raw_results->diag_results); - set.name = "Signal to high prio thread"; + set.name = "Signal to high prio thread (early processing)"; json_array_append_new(array, result_set_to_json(set)); + result = process_result(N_RUNS, raw_results->lo_prio_results, desc); + set.name = "Signal to high prio thread"; + json_array_append_new(array, result_set_to_json(set)); result = process_result(N_RUNS, raw_results->hi_prio_results, desc); set.name = "Signal to low prio thread"; diff --git a/apps/signal/CMakeLists.txt b/apps/signal/CMakeLists.txt index 83850c51..0ba66e87 100644 --- a/apps/signal/CMakeLists.txt +++ b/apps/signal/CMakeLists.txt @@ -18,13 +18,6 @@ config_option( DEPENDS "DefaultBenchDeps" ) -config_option( - AppSignalEarlyProcessing - APP_SIGNAL_EARLYPROC - "Apply early processing of the raw results for Signal benchmark" - DEFAULT - OFF -) add_config_library(sel4benchsignal "${configure_string}") diff --git a/apps/signal/src/main.c b/apps/signal/src/main.c index 2be21058..6c92023b 100644 --- a/apps/signal/src/main.c +++ b/apps/signal/src/main.c @@ -81,8 +81,6 @@ void low_prio_signal_fn(int argc, char **argv) seL4_Wait(ntfn, NULL); } -#if defined CONFIG_APP_SIGNAL_EARLYPROC - /* The same as low_prio_signal_fn, but implements * early processing of samples ("Early processing methodology") * @@ -95,7 +93,6 @@ void low_prio_signal_fn(int argc, char **argv) * Variable "is_counted" indicates whether the sample will be * dropped (as warm-up one) or "counted". */ - void low_prio_signal_early_proc_fn(int argc, char **argv) { assert(argc == N_LO_SIGNAL_ARGS); @@ -107,23 +104,17 @@ void low_prio_signal_early_proc_fn(int argc, char **argv) /* extract overhead value from the global structure */ ccnt_t overhead = results->overhead_min; - ccnt_t sample = 0; ccnt_t sum = 0; ccnt_t sum2 = 0; + DATACOLLECT_INIT(); + for (seL4_Word i = 0; i < N_RUNS; i++) { ccnt_t start; - seL4_Word is_counted; - - is_counted = (~(i - N_IGNORED)) >> (seL4_WordBits - 1); SEL4BENCH_READ_CCNT(start); DO_REAL_SIGNAL(ntfn); - - sample = is_counted * (*end - start - overhead); - - sum += sample; - sum2 += sample * sample; + DATACOLLECT_GET_SUMS(i, N_IGNORED, start, *end, overhead, sum, sum2); } results->lo_sum = sum; @@ -136,8 +127,6 @@ void low_prio_signal_early_proc_fn(int argc, char **argv) seL4_Wait(ntfn, NULL); } -#endif /* CONFIG_APP_SIGNAL_EARLYPROC */ - void high_prio_signal_fn(int argc, char **argv) { assert(argc == N_HI_SIGNAL_ARGS); @@ -212,17 +201,15 @@ static void benchmark(env_t *env, seL4_CPtr ep, seL4_CPtr ntfn, signal_results_t .fn = (sel4utils_thread_entry_fn) wait_fn, }; -#if defined CONFIG_APP_SIGNAL_EARLYPROC helper_thread_t signal = { .argc = N_LO_SIGNAL_ARGS, - .fn = (sel4utils_thread_entry_fn) low_prio_signal_early_proc_fn, + .fn = (sel4utils_thread_entry_fn) low_prio_signal_fn, }; -#else - helper_thread_t signal = { + + helper_thread_t signal_early_proc = { .argc = N_LO_SIGNAL_ARGS, - .fn = (sel4utils_thread_entry_fn) low_prio_signal_fn, + .fn = (sel4utils_thread_entry_fn) low_prio_signal_early_proc_fn, }; -#endif ccnt_t end; UNUSED int error; @@ -232,24 +219,30 @@ static void benchmark(env_t *env, seL4_CPtr ep, seL4_CPtr ntfn, signal_results_t /* first benchmark signalling to a higher prio thread */ benchmark_configure_thread(env, ep, seL4_MaxPrio, "wait", &wait.thread); benchmark_configure_thread(env, ep, seL4_MaxPrio - 1, "signal", &signal.thread); + benchmark_configure_thread(env, ep, seL4_MaxPrio - 1, "signal early", &signal_early_proc.thread); sel4utils_create_word_args(wait.argv_strings, wait.argv, wait.argc, ntfn, ep, (seL4_Word) &end); - -#if defined CONFIG_APP_SIGNAL_EARLYPROC - sel4utils_create_word_args(signal.argv_strings, signal.argv, signal.argc, ntfn, - (seL4_Word) &end, (seL4_Word) results, ep); -#else sel4utils_create_word_args(signal.argv_strings, signal.argv, signal.argc, ntfn, (seL4_Word) &end, (seL4_Word) results->lo_prio_results, ep); -#endif + sel4utils_create_word_args(signal_early_proc.argv_strings, signal_early_proc.argv, signal_early_proc.argc, ntfn, + (seL4_Word) &end, (seL4_Word) results, ep); + + /* Late processing run*/ start_threads(&signal, &wait); benchmark_wait_children(ep, "children of notification benchmark", 2); stop_threads(&signal, &wait); + /* Early processing run*/ + start_threads(&signal_early_proc, &wait); + + benchmark_wait_children(ep, "children of notification benchmark", 2); + + stop_threads(&signal_early_proc, &wait); + seL4_CPtr auth = simple_get_tcb(&env->simple); /* now benchmark signalling to a lower prio thread */ error = seL4_TCB_SetPriority(wait.thread.tcb.cptr, auth, seL4_MaxPrio - 1); @@ -285,8 +278,6 @@ void measure_signal_overhead(seL4_CPtr ntfn, ccnt_t *results) } } -#if defined CONFIG_APP_SIGNAL_EARLYPROC - /* * Execution flow for Early Processing: we have to calculate Min value * of measured overhead before running Signal benchmark. @@ -305,8 +296,6 @@ ccnt_t getMinOverhead(ccnt_t overhead[N_RUNS]) return min; } -#endif /* CONFIG_APP_SIGNAL_EARLYPROC */ - static env_t *env; void CONSTRUCTOR(MUSLCSYS_WITH_VSYSCALL_PRIORITY) init_env(void) @@ -349,8 +338,6 @@ int main(int argc, char **argv) /* measure overhead */ measure_signal_overhead(ntfn.cptr, results->overhead); -#if defined CONFIG_APP_SIGNAL_EARLYPROC - /* TODO: integrate checking stability of the overhead. * Currently (04.06.2022) only x86_64 platform has unstable overhead and it's allowed, * so we just blindly subtract "Min" overhead from all the measurements. @@ -361,8 +348,6 @@ int main(int argc, char **argv) */ results->overhead_min = getMinOverhead(results->overhead); -#endif /* CONFIG_APP_SIGNAL_EARLYPROC */ - benchmark(env, done_ep.cptr, ntfn.cptr, results); /* done -> results are stored in shared memory so we can now return */ diff --git a/libsel4benchsupport/include/benchmark.h b/libsel4benchsupport/include/benchmark.h index 5bc3a8f5..7441b14e 100644 --- a/libsel4benchsupport/include/benchmark.h +++ b/libsel4benchsupport/include/benchmark.h @@ -28,6 +28,25 @@ #define MAX_TIMER_IRQS 4 +/* Data collection support macros, to be used in individual benchmark apps*/ + +/* Declare and init internal parameters: "sample" and "is_counted" */ +#define DATACOLLECT_INIT() ccnt_t sample = 0; seL4_Word is_counted; + +/* Find out if "i"-th sample will be recorded (if "i" less than "n", + * the sample will be ignored. + * Then calculate sample using start value "s", end value "e" and + * value of overhead "o". + * Then accumulate sum of samples "par_sum" and sum of squared samples + * "par_sum2". + */ +#define DATACOLLECT_GET_SUMS(i, n, s, e, o, par_sum, par_sum2) \ +{\ +is_counted = ( ~(i - n) ) >> (seL4_WordBits - 1);\ +sample = is_counted * (e - s - o);\ +par_sum += sample; par_sum2 += sample * sample;\ +} + /* benchmarking environment set up by root task */ typedef struct env { /* vka interface for allocating *fast* objects in the benchmark */ diff --git a/libsel4benchsupport/include/sel4benchsupport/signal.h b/libsel4benchsupport/include/sel4benchsupport/signal.h index b755844f..2595715a 100644 --- a/libsel4benchsupport/include/sel4benchsupport/signal.h +++ b/libsel4benchsupport/include/sel4benchsupport/signal.h @@ -12,13 +12,17 @@ #define N_RUNS (100 + N_IGNORED) typedef struct signal_results { + /* Data for late processing */ ccnt_t lo_prio_results[N_RUNS]; ccnt_t hi_prio_results[N_RUNS]; - ccnt_t overhead[N_RUNS]; ccnt_t hi_prio_average[N_RUNS][NUM_AVERAGE_EVENTS]; - /* Parameters intrinsic to early processing */ + ccnt_t overhead[N_RUNS]; /* "overhead" is used by early processing as well */ + /* Data for early processing */ ccnt_t lo_sum; /* sum of samples */ ccnt_t lo_sum2; /* sum of squared samples */ ccnt_t lo_num; /* number of samples to process */ ccnt_t overhead_min; /* min overhead found in "overhead" array */ + /* array required by report output function + Zeros, but can be used for diagnostic data */ + ccnt_t diag_results[N_RUNS]; /* array required by report output function */ } signal_results_t;