From 6fbe9ecf91ffeba67b05f22d006e8f91f7f43192 Mon Sep 17 00:00:00 2001 From: Ivan Krylov Date: Fri, 10 Nov 2017 17:03:07 +0300 Subject: [PATCH 1/2] Implement throughput calculation --- main.c | 16 +++++++++++----- metrics.c | 12 +++++++++--- metrics.h | 6 +++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index 910f456..5b0d1c0 100644 --- a/main.c +++ b/main.c @@ -623,7 +623,7 @@ static int populate_dataset(struct thread_context *ctx) { int sres = -1; if (end > ctx->offset) - ctx->offset = 0; + ctx->offset = 0; if (verbose) { fprintf(stderr, "Populating from %d to %d\n", ctx->offset, end); @@ -958,7 +958,7 @@ int main(int argc, char **argv) { case 'h': add_host(optarg); break; case 'T': runtime_limit = atol(optarg); - break; + break; case 'i': no_items = atoi(optarg); break; case 's': srand(atoi(optarg)); @@ -1085,7 +1085,7 @@ int main(int argc, char **argv) { start_time = (int) time (NULL); if (runtime_limit > 0) { - alarm(runtime_limit); + alarm(runtime_limit); } } size_t nget = 0; @@ -1094,7 +1094,9 @@ int main(int argc, char **argv) { pthread_t *threads = calloc(sizeof(pthread_t), no_threads); struct thread_context *ctx = calloc(sizeof(struct thread_context), no_threads); int ii; + struct timespec local_start, local_end={0,0}; + if (clock_gettime(CLOCK_MONOTONIC, &local_start)) abort(); if (no_iterations > 0) { int perThread = no_iterations / no_threads; int rest = no_iterations % no_threads; @@ -1118,13 +1120,17 @@ int main(int argc, char **argv) { assert(ret == (void*)&ctx[ii]); if (verbose) { fprintf(stdout, "Details from thread %d\n", ii); - print_metrics(&ctx[ii]); + print_metrics(&ctx[ii], &local_end); } } } + if (clock_gettime(CLOCK_MONOTONIC, &local_end)) abort(); + local_end.tv_sec -= local_start.tv_sec; + local_end.tv_nsec -= local_start.tv_nsec; fprintf(stdout, "Average with %d threads\n", no_threads); - print_aggregated_metrics(ctx, no_threads); + print_aggregated_metrics(ctx, no_threads, &local_end); + free(threads); free(ctx); } while (loop); diff --git a/metrics.c b/metrics.c index 119b707..0b72bdd 100644 --- a/metrics.c +++ b/metrics.c @@ -166,19 +166,25 @@ static void print_details(enum TxnType tx_type, struct ResultMetrics *r) { hrtime2text(r->max99th_result, tmax99, sizeof(tmax99))); } -void print_metrics(struct thread_context *ctx) { +void print_metrics(struct thread_context *ctx, struct timespec * time) { + long total_count = 0; for (int ii = 0; ii < TX_CAS - TX_GET; ++ii) { if (ctx->tx[ii].current > 0) { struct ResultMetrics *r = calc_metrics(ii, ctx); if (r) { print_details(ii, r); + total_count += r->success_count; free(r); } } } + if (time->tv_sec && time->tv_nsec) { + double throughput = total_count/(time->tv_sec + 1e-9*time->tv_nsec); + fprintf(stdout, "Throughput: %g s^-1\n", throughput); + } } -void print_aggregated_metrics(struct thread_context *ctx, int num) +void print_aggregated_metrics(struct thread_context *ctx, int num, struct timespec * time) { int total = 0; for (int ii = 0; ii < num; ++ii) { @@ -197,5 +203,5 @@ void print_aggregated_metrics(struct thread_context *ctx, int num) } } - print_metrics(&context); + print_metrics(&context, time); } diff --git a/metrics.h b/metrics.h index e1566fb..4cb65f0 100644 --- a/metrics.h +++ b/metrics.h @@ -39,8 +39,8 @@ struct thread_context; void record_tx(enum TxnType, hrtime_t, struct thread_context *); struct ResultMetrics *calc_metrics(enum TxnType tx_type, struct thread_context *); -void print_metrics(struct thread_context *); -void print_aggregated_metrics(struct thread_context *, int); +void print_metrics(struct thread_context *, struct timespec *); +void print_aggregated_metrics(struct thread_context *, int, struct timespec *); struct ResultMetrics { hrtime_t max_result; @@ -53,7 +53,7 @@ struct ResultMetrics { long error_count; }; -#ifdef __cplusplus +#ifdef __cplusplus } #endif From d7cf2b9b27498849d590c8b79c7ba8820bf8ba45 Mon Sep 17 00:00:00 2001 From: Ivan Krylov Date: Fri, 10 Nov 2017 17:11:11 +0300 Subject: [PATCH 2/2] Proper time difference calculation (double vs incorrect timespec subtraction) --- main.c | 9 ++++----- metrics.c | 10 +++++----- metrics.h | 4 ++-- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/main.c b/main.c index 5b0d1c0..1db0b5f 100644 --- a/main.c +++ b/main.c @@ -1094,7 +1094,7 @@ int main(int argc, char **argv) { pthread_t *threads = calloc(sizeof(pthread_t), no_threads); struct thread_context *ctx = calloc(sizeof(struct thread_context), no_threads); int ii; - struct timespec local_start, local_end={0,0}; + struct timespec local_start, local_end; if (clock_gettime(CLOCK_MONOTONIC, &local_start)) abort(); if (no_iterations > 0) { @@ -1120,16 +1120,15 @@ int main(int argc, char **argv) { assert(ret == (void*)&ctx[ii]); if (verbose) { fprintf(stdout, "Details from thread %d\n", ii); - print_metrics(&ctx[ii], &local_end); + print_metrics(&ctx[ii], 0); } } } if (clock_gettime(CLOCK_MONOTONIC, &local_end)) abort(); - local_end.tv_sec -= local_start.tv_sec; - local_end.tv_nsec -= local_start.tv_nsec; + double time_diff = 1e-9*(local_end.tv_nsec - local_start.tv_nsec) + local_end.tv_sec - local_start.tv_sec; fprintf(stdout, "Average with %d threads\n", no_threads); - print_aggregated_metrics(ctx, no_threads, &local_end); + print_aggregated_metrics(ctx, no_threads, time_diff); free(threads); free(ctx); diff --git a/metrics.c b/metrics.c index 0b72bdd..6cca82c 100644 --- a/metrics.c +++ b/metrics.c @@ -166,7 +166,7 @@ static void print_details(enum TxnType tx_type, struct ResultMetrics *r) { hrtime2text(r->max99th_result, tmax99, sizeof(tmax99))); } -void print_metrics(struct thread_context *ctx, struct timespec * time) { +void print_metrics(struct thread_context *ctx, double timediff) { long total_count = 0; for (int ii = 0; ii < TX_CAS - TX_GET; ++ii) { if (ctx->tx[ii].current > 0) { @@ -178,13 +178,13 @@ void print_metrics(struct thread_context *ctx, struct timespec * time) { } } } - if (time->tv_sec && time->tv_nsec) { - double throughput = total_count/(time->tv_sec + 1e-9*time->tv_nsec); + if (timediff) { + double throughput = total_count/timediff; fprintf(stdout, "Throughput: %g s^-1\n", throughput); } } -void print_aggregated_metrics(struct thread_context *ctx, int num, struct timespec * time) +void print_aggregated_metrics(struct thread_context *ctx, int num, double timediff) { int total = 0; for (int ii = 0; ii < num; ++ii) { @@ -203,5 +203,5 @@ void print_aggregated_metrics(struct thread_context *ctx, int num, struct timesp } } - print_metrics(&context, time); + print_metrics(&context, timediff); } diff --git a/metrics.h b/metrics.h index 4cb65f0..689b3b4 100644 --- a/metrics.h +++ b/metrics.h @@ -39,8 +39,8 @@ struct thread_context; void record_tx(enum TxnType, hrtime_t, struct thread_context *); struct ResultMetrics *calc_metrics(enum TxnType tx_type, struct thread_context *); -void print_metrics(struct thread_context *, struct timespec *); -void print_aggregated_metrics(struct thread_context *, int, struct timespec *); +void print_metrics(struct thread_context *, double); +void print_aggregated_metrics(struct thread_context *, int, double); struct ResultMetrics { hrtime_t max_result;