Skip to content

Commit

Permalink
[ISSUE-0051]: performace tests measure time outside internal loop
Browse files Browse the repository at this point in the history
  • Loading branch information
SzigetiJ committed Jan 9, 2024
1 parent dd27c52 commit d3bf734
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 118 deletions.
20 changes: 5 additions & 15 deletions tests/performance/add_perf128.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
#include <stdio.h>
#include <time.h>

#include "biguint128.h"
#include "perf_common.h"
#include "perf_common128.h"


// ### Constraints and default values
#define BUFLEN 40 // for full function names
const StandardConstraints LIMITS = {
8,
(1<<28) // 256M loops
Expand Down Expand Up @@ -41,19 +37,15 @@ const char *funname[]={
"sub_replace",
"sub_tiny"
};
const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]);
const unsigned int fun_n = ARRAYSIZE(funname);

// ### Internal functions
static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int fun, const StandardArgs *args) {
static unsigned int exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int fun, const StandardArgs *args, UInt *chkval) {
BigUInt128 a = get_value_by_level(ai, args->levels);
BigUInt128 b = get_value_by_level(bi, args->levels);
BigUInt128 chkval = biguint128_ctor_default();
BigUInt128 res;
BigUInt128 *procref = (fun & 1) ? &a : &res; // note, every second function is an assignment operation
clock_t t0, t1;
char fnamebuf[BUFLEN];

t0 = clock();
for (unsigned int i = 0; i < args->loops; ++i) {
if (!(fun & 4)) { // lower 4 functions
if (fun == FUN_ADD) {
Expand All @@ -76,15 +68,13 @@ static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int f
biguint128_sub_replace(&res, &a, &b);
}
}
process_result_v1(procref, &chkval.dat[0]);
process_result_v1(procref, chkval);
inc_operands_v1(&a, &b, args->diff_a, args->diff_b);
}
t1 = clock();
snprintf(fnamebuf, BUFLEN, "%s + 2*add_tiny(C)", funname[fun]);
print_exec_summary(t0, t1, fnamebuf, args->loops, &chkval, 1);
return args->loops;
}

// ### Main function
int main(int argc, const char *argv[]) {
return fun2_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_);
return fun2_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_, 1);
}
17 changes: 5 additions & 12 deletions tests/performance/div1000_perf128.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <time.h>

#include "biguint128.h"
#include "perf_common.h"
#include "perf_common128.h"
Expand All @@ -25,29 +23,24 @@ const char *funname[] = {
};
const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]);

static void exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args) {
static unsigned int exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args, UInt *chkval) {
BigUInt128 a = get_value_by_level(ai, args->levels);
BigUInt128 chkval = biguint128_ctor_default();
uint32_t loop_cnt;
clock_t t0, t1;

BigUInt128 bdiv = biguint128_value_of_uint(1000);
BigUIntPair128 res;

t0 = clock();
for (loop_cnt = 0; loop_cnt < args->loops; ++loop_cnt) {
res = (fun==VARIANT_DIV1000_X)?
biguint128_div1000(&a):
biguint128_div(&a, &bdiv);
process_result_v1(&res.first, &chkval.dat[0]);
process_result_v1(&res.second, &chkval.dat[0]);
process_result_v1(&res.first, &chkval[0]);
process_result_v1(&res.second, &chkval[1]);
biguint128_add_tiny(&a, (UInt)args->diff_a);
}
t1 = clock();

print_exec_summary(t0, t1, funname[fun], loop_cnt, &chkval, 1);
return loop_cnt;
}

int main(int argc, const char *argv[]) {
return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_);
return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_, 2);
}
22 changes: 6 additions & 16 deletions tests/performance/div10_perf128.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <time.h>

#include "biguint128.h"
#include "perf_common.h"
#include "perf_common128.h"
Expand Down Expand Up @@ -29,22 +27,16 @@ const char *funname[] = {
"div10(x)"
};

static void exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args) {
static unsigned int exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args, UInt *chkval) {
const BigUInt128 bdiv = biguint128_value_of_uint(10);
BigUInt128 a = get_value_by_level(ai, args->levels);
BigUInt128 chkval[] = {
biguint128_ctor_default(),
biguint128_ctor_default()
};
BigUInt128 res0;
BigUIntPair128 res;
BigUIntTinyPair128 rest;
BigUInt128 *procref1 = fun == VARIANT_DIV10_X?&rest.first:&res.first;
UInt *procref2 = fun == VARIANT_DIV10_X?&rest.second:&res.second.dat[0];
uint32_t loop_cnt;
clock_t t0, t1;
unsigned int loop_cnt;

t0 = clock();
for (loop_cnt = 0; loop_cnt < args->loops; ++loop_cnt) {
if (fun == VARIANT_DIV_X_10) {
res = biguint128_div(&a, &bdiv);
Expand All @@ -59,15 +51,13 @@ static void exec_function_loop_(unsigned int ai, unsigned int fun, const Standar
} else {
rest = biguint128_div10(&a);
}
process_result_v1(procref1, &chkval[0].dat[0]);
process_result_v3(procref2, &chkval[1].dat[0]);
process_result_v1(procref1, &chkval[0]);
process_result_v3(procref2, &chkval[1]);
biguint128_add_tiny(&a, (UInt) args->diff_a);
}
t1 = clock();

print_exec_summary(t0, t1, funname[fun], loop_cnt, chkval, 2);
return loop_cnt;
}

int main(int argc, const char *argv[]) {
return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, sizeof(funname) / sizeof(funname[0]), funname, &exec_function_loop_);
return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, sizeof(funname) / sizeof(funname[0]), funname, &exec_function_loop_,2);
}
18 changes: 6 additions & 12 deletions tests/performance/mul_perf128.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <time.h>

#include "biguint128.h"
#include "perf_common.h"
#include "perf_common128.h"
Expand Down Expand Up @@ -29,21 +27,18 @@ const char *funname[]={
"dmul",
"div"
};
const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]);
const unsigned int fun_n = ARRAYSIZE(funname);


// ### Internal functions
static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int fun, const StandardArgs *args) {
static unsigned int exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int fun, const StandardArgs *args, UInt *chkval) {
BigUInt128 a = get_value_by_level(ai, args->levels);
BigUInt128 b = get_value_by_level(bi, args->levels);
BigUInt128 chkval = biguint128_ctor_default();
BigUInt128 res;
BigUIntPair128 resp;
BigUInt128 *procref1 = fun == FUN_MUL ? &res : &resp.first;
BigUInt128 *procref2 = fun == FUN_MUL ? &res : &resp.second;
clock_t t0, t1;

t0 = clock();
for (unsigned int i = 0; i < args->loops; ++i) {
if (fun == FUN_MUL) {
res = biguint128_mul(&a, &b);
Expand All @@ -52,15 +47,14 @@ static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int f
} else if (fun == FUN_DIV) {
resp = biguint128_div(&a, &b);
}
process_result_v1(procref2, &chkval.dat[0]);
process_result_v1(procref1, &chkval.dat[0]);
process_result_v1(procref2, chkval+0);
process_result_v1(procref1, chkval+1);
inc_operands_v1(&a, &b, (UInt) args->diff_a, (UInt) args->diff_b);
}
t1 = clock();
print_exec_summary(t0, t1, funname[fun], args->loops, &chkval, 1);
return args->loops;
}

// ### Main function
int main(int argc, const char *argv[]) {
return fun2_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_);
return fun2_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_, 2);
}
12 changes: 4 additions & 8 deletions tests/performance/parse_perf128.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,29 +46,25 @@ const unsigned int fun_n = ARRAYSIZE(funname);


// ### Internal functions
static void exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args) {
static unsigned int exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args, UInt *chkval) {
char str[DECDIGITS];
memset(str, '1', DECDIGITS);
buint_size_t str_n = (numwidth[fun] * (ai + 1)) / args->levels;
BigUInt128 chkval = biguint128_ctor_default();
BigUInt128 res;
clock_t t0, t1;

t0 = clock();
for (unsigned int i = 0; i < args->loops; ++i) {
if (fun == FUN_PARSE_HEX) {
res = biguint128_ctor_hexcstream(str, str_n);
} else if (fun == FUN_PARSE_DEC) {
res = biguint128_ctor_deccstream(str, str_n);
}
process_result_v1(&res, &chkval.dat[0]);
process_result_v1(&res, chkval);
str[i % str_n] = '0' + ((i * args->diff_a) % 10);
}
t1 = clock();
print_exec_summary(t0, t1, funname[fun], args->loops, &chkval, 1);
return args->loops;
}

// ### Main function
int main(int argc, const char *argv[]) {
return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_);
return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_, 1);
}
42 changes: 36 additions & 6 deletions tests/performance/perf_common.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include "perf_common.h"

Expand Down Expand Up @@ -92,6 +93,19 @@ void print_help_all(const char *prgname, unsigned int bits, unsigned int argmask
}
}

static inline void print_exec_time(clock_t t_begin, clock_t t_end, const char *op, int cnt, unsigned int bits) {
clock_t dt = t_end - t_begin;
fprintf(stdout, "=== %d BigUInt%u %s operations ===\n", cnt, bits, op);
fprintf(stdout, " Elapsed time: %ld us,\t%.1f op/s\n", dt, (1000000.0 * cnt) / dt);
}

static inline void print_exec_summary(clock_t t_begin, clock_t t_end, const char *op, unsigned int bits, int cnt, const UInt *val, int valnum) {
print_exec_time(t_begin, t_end, op, cnt, bits);
for (unsigned int i=0; i<valnum; ++i) {
fprintf(stdout, " Check value #%u: %"PRIuint"\n", i+1, val[i]);
}
}

static inline int check_args_(const char *prgname, StandardArgs *args,
unsigned int bits,
const StandardConstraints *max,
Expand Down Expand Up @@ -123,7 +137,9 @@ static inline int check_args_(const char *prgname, StandardArgs *args,
int fun2_main(int argc, const char *argv[],
unsigned int bits, const StandardArgs args_init, const StandardConstraints *max,
unsigned int fun_n, const char *funname[],
void (*internal_loop)(unsigned int ai, unsigned int bi, unsigned int funidx, const StandardArgs *args)) {
LoopFunction2 internal_loop,
unsigned int chkval_n
) {
StandardArgs args = parse_args(argc, argv, args_init);
int check_res = check_args_(argv[0], &args, bits, max, fun_n, funname, -1);
if (check_res) return check_res;
Expand All @@ -135,8 +151,14 @@ int fun2_main(int argc, const char *argv[],
fprintf(stderr, "*** Operand levels: a #%u, b #%u ***\n", ai, bi);

for (unsigned int fi = 0; fi < fun_n; ++fi) {
if ((args.fmask & (1<<fi)) && !(args.fexmask & (1<<fi))) {
internal_loop(ai, bi, fi, &args);
if ((args.fmask & (1 << fi)) && !(args.fexmask & (1 << fi))) {
UInt chkval[]={0,0};
clock_t t0, t1;

t0 = clock();
unsigned int loops = internal_loop(ai, bi, fi, &args, chkval);
t1 = clock();
print_exec_summary(t0, t1, funname[fi], bits, loops, chkval, chkval_n);
}
}

Expand All @@ -148,7 +170,9 @@ int fun2_main(int argc, const char *argv[],
int fun1_main(int argc, const char *argv[],
unsigned int bits, const StandardArgs args_init, const StandardConstraints *max,
unsigned int fun_n, const char *funname[],
void (*internal_loop)(unsigned int ai, unsigned int funidx, const StandardArgs *args)) {
LoopFunction1 internal_loop,
unsigned int chkval_n
) {
StandardArgs args = parse_args(argc, argv, args_init);
int check_res = check_args_(argv[0], &args, bits, max, fun_n, funname, ARGMASK_ALL - ARGMASK_LMASKB - ARGMASK_DIFFB);
if (check_res) return check_res;
Expand All @@ -158,8 +182,14 @@ int fun1_main(int argc, const char *argv[],
fprintf(stderr, "*** Operand level: a #%u ***\n", ai);

for (unsigned int fi = 0; fi < fun_n; ++fi) {
if ((args.fmask & (1<<fi)) && !(args.fexmask & (1<<fi))) {
internal_loop(ai, fi, &args);
if ((args.fmask & (1 << fi)) && !(args.fexmask & (1 << fi))) {
UInt chkval[]={0,0};
clock_t t0, t1;

t0 = clock();
unsigned int loops = internal_loop(ai, fi, &args, chkval);
t1 = clock();
print_exec_summary(t0, t1, funname[fi], bits, loops, chkval, chkval_n);
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions tests/performance/perf_common.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef PERF_COMMON_H
#define PERF_COMMON_H
#include <stdbool.h>
#include "uint_types.h"

typedef struct {
unsigned int levels;
Expand All @@ -20,6 +21,10 @@ typedef struct {
unsigned int fexmask;
} StandardArgs;

typedef unsigned int (*LoopFunction2)(unsigned int ai, unsigned int bi, unsigned int funidx, const StandardArgs *args, UInt *chkval);
typedef unsigned int (*LoopFunction1)(unsigned int ai, unsigned int funidx, const StandardArgs *args, UInt *chkval);
typedef unsigned int (*LoopFunctionN)(unsigned int *xi, unsigned int funidx, const StandardArgs *args, UInt *chkval);

#define ARGMASK_LOOPS 1U
#define ARGMASK_LEVELS 2U
#define ARGMASK_LMASKA 4U
Expand All @@ -40,11 +45,12 @@ void print_help_all(const char *prgname, unsigned int bits, unsigned int argmask
int fun2_main(int argc, const char *argv[],
unsigned int bits, const StandardArgs args_init, const StandardConstraints *max,
unsigned int fun_n, const char *funname[],
void (*internal_loop)(unsigned int ai, unsigned int bi, unsigned int funidx, const StandardArgs *args));
LoopFunction2 internal_loop,
unsigned int chkval_n);
int fun1_main(int argc, const char *argv[],
unsigned int bits, const StandardArgs args_init, const StandardConstraints *max,
unsigned int fun_n, const char *funname[],
void (*internal_loop)(unsigned int ai, unsigned int funidx, const StandardArgs *args));

LoopFunction1 internal_loop,
unsigned int chkval_n);
#endif /* PERF_COMMON_H */

16 changes: 0 additions & 16 deletions tests/performance/perf_common128.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#define _PERF_COMMON_H_

#include <stdio.h>
#include <time.h>

#include "biguint128.h"

Expand All @@ -15,21 +14,6 @@ typedef struct {
BigUInt128 val[3];
} PerfTestInitValues;

static inline void print_exec_time(clock_t t_begin, clock_t t_end, const char *op, int cnt) {
clock_t dt = t_end - t_begin;
fprintf(stdout, "=== %d BigUInt128 %s operations ===\n", cnt, op);
fprintf(stdout, " Elapsed time: %ld us,\t%.1f op/s\n", dt, (1000000.0 * cnt) / dt);
}

static inline void print_exec_summary(clock_t t_begin, clock_t t_end, const char *op, int cnt, const BigUInt128 *val, int valnum) {
char buf[DEC_BIGUINTLEN];
print_exec_time(t_begin, t_end, op, cnt);
for (int i=0; i<valnum; ++i) {
buf[biguint128_print_dec(val+i, buf, DEC_BIGUINTLEN-1)] = 0;
fprintf(stdout, " Check value #%d: %s\n", i+1, buf);
}
}

static inline PerfTestInitValues get_std_initvalues() {
PerfTestInitValues retv = {
{"low","medium","high"}
Expand Down
Loading

0 comments on commit d3bf734

Please sign in to comment.