From c06cf216e87983ed4943a109b6a89f82387873fe Mon Sep 17 00:00:00 2001 From: Yolan Romailler Date: Wed, 7 Dec 2016 15:01:50 +0100 Subject: [PATCH 1/5] Adding comments related to the variance. Since it may not be straightforward. (Yet, one should definitively check out Welford method to get it, I agree.) --- src/ttest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ttest.c b/src/ttest.c index 430384c..8915212 100644 --- a/src/ttest.c +++ b/src/ttest.c @@ -24,11 +24,13 @@ void t_push(t_ctx *ctx, double x, uint8_t class) { // see Knuth Vol 2 double delta = x - ctx->mean[class]; ctx->mean[class] = ctx->mean[class] + delta / ctx->n[class]; + // note this is not yet unbiased ctx->m2[class] = ctx->m2[class] + delta * (x - ctx->mean[class]); } double t_compute(t_ctx *ctx) { double var[2] = {0.0, 0.0}; + // to obtain the sample variance, we unbiase: var[0] = ctx->m2[0] / (ctx->n[0] - 1); var[1] = ctx->m2[1] / (ctx->n[1] - 1); double num = (ctx->mean[0] - ctx->mean[1]); From b8c61534ed46a8f82e841845ac439ea637ef72ca Mon Sep 17 00:00:00 2001 From: Yolan Romailler Date: Wed, 7 Dec 2016 15:03:57 +0100 Subject: [PATCH 2/5] Adding comments Since this is not straightforward. --- inc/ttest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/ttest.h b/inc/ttest.h index e6722a0..006871d 100644 --- a/inc/ttest.h +++ b/inc/ttest.h @@ -1,6 +1,6 @@ typedef struct { double mean[2]; - double m2[2]; + double m2[2]; // m2, once divided by n-1 provides the sample variance double n[2]; } t_ctx; From 5f1b18aad6848f79dc8bcf4e8cc75fb8a29a0ab5 Mon Sep 17 00:00:00 2001 From: Yolan Romailler Date: Wed, 7 Dec 2016 15:16:10 +0100 Subject: [PATCH 3/5] Adding details about what's doing what. So it's easier to use without reading the code entirely. --- inc/fixture.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/inc/fixture.h b/inc/fixture.h index e86a5bd..fa7ba0e 100644 --- a/inc/fixture.h +++ b/inc/fixture.h @@ -1,5 +1,14 @@ +// chunck_size is the size of the data to be provided to the tested function extern const size_t chunk_size; +// number_measurements allows to set the number of measurements per pass, +// note that currently the report awaits enough_measurements = 10000 measurements. extern const size_t number_measurements; +// do_one_computation would typically be one or more passes of the functions +// you're timing using the input in range chunk_size pointed by data extern uint8_t do_one_computation(uint8_t *data); +// init_dut provides a mean to perform some initializations at startup extern void init_dut(void); +// prepare_inputs allows one to provide the input data. Dudect will try +// and find discrepancies between the distributions of the data +// labelled in class 0 and class 1. extern void prepare_inputs(uint8_t *input_data, uint8_t *classes); From 3e891047c552bbec5491d4903f47f1198f74822f Mon Sep 17 00:00:00 2001 From: Yolan Romailler Date: Wed, 7 Dec 2016 15:28:06 +0100 Subject: [PATCH 4/5] Move unnecessary local variable ticks in measure() This improves readability and clearly we always want to differentiate after we measure, so it is nicer to have the "temporary" ticks variables in there too. --- src/fixture.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/fixture.c b/src/fixture.c index 25359d4..d743476 100644 --- a/src/fixture.c +++ b/src/fixture.c @@ -65,12 +65,21 @@ static void prepare_percentiles(int64_t *ticks) { } } -static void measure(int64_t *ticks, uint8_t *input_data) { +static void measure(int64_t *exec_times, uint8_t *input_data) { + int64_t *ticks = calloc(number_measurements + 1, sizeof(int64_t)); + if (!ticks) { + die(); + } + for (size_t i = 0; i < number_measurements; i++) { ticks[i] = cpucycles(); do_one_computation(input_data + i * chunk_size); } ticks[number_measurements] = cpucycles(); + + differentiate(exec_times, ticks); // inplace + + free(ticks); } static void differentiate(int64_t *exec_times, int64_t *ticks) { @@ -195,15 +204,11 @@ static void report(void) { static void doit(void) { // XXX move these callocs to parent - int64_t *ticks = calloc(number_measurements + 1, sizeof(int64_t)); int64_t *exec_times = calloc(number_measurements, sizeof(int64_t)); uint8_t *classes = calloc(number_measurements, sizeof(uint8_t)); uint8_t *input_data = calloc(number_measurements * chunk_size, sizeof(uint8_t)); - if (!ticks) { - die(); - } if (!classes) { die(); } @@ -212,8 +217,7 @@ static void doit(void) { } prepare_inputs(input_data, classes); - measure(ticks, input_data); - differentiate(exec_times, ticks); // inplace + measure(exec_times, input_data); if (percentiles[number_percentiles - 1] == 0) { prepare_percentiles(exec_times); @@ -222,7 +226,6 @@ static void doit(void) { report(); } - free(ticks); free(classes); free(input_data); } From 40d9df93138d7f0bcb0af4f233c25105ca0f96bb Mon Sep 17 00:00:00 2001 From: AnomalRoil Date: Wed, 7 Dec 2016 15:36:50 +0100 Subject: [PATCH 5/5] Correcting a typo --- src/ttest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ttest.c b/src/ttest.c index 8915212..ea5132f 100644 --- a/src/ttest.c +++ b/src/ttest.c @@ -30,7 +30,7 @@ void t_push(t_ctx *ctx, double x, uint8_t class) { double t_compute(t_ctx *ctx) { double var[2] = {0.0, 0.0}; - // to obtain the sample variance, we unbiase: + // to obtain the sample variance, we unbias: var[0] = ctx->m2[0] / (ctx->n[0] - 1); var[1] = ctx->m2[1] / (ctx->n[1] - 1); double num = (ctx->mean[0] - ctx->mean[1]);