From 63f480dfdfd43499104468e1786b6514c03c0cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZIGETI=20J=C3=A1nos?= Date: Mon, 8 Jan 2024 18:14:46 +0100 Subject: [PATCH] [ISSUE-0051]: perf tests rebased on perf_common. Except: parse/shift. --- tests/performance/add_perf128.c | 28 ++++----- tests/performance/div1000_perf128.c | 61 +++++++++---------- tests/performance/div10_perf128.c | 94 +++++++++++++++-------------- tests/performance/mul_perf128.c | 36 ++++------- tests/performance/perf_common.c | 24 ++++---- tests/performance/perf_common.h | 14 +++-- tests/performance/perf_common128.h | 6 +- tests/performance/print_perf128.c | 31 +++------- 8 files changed, 138 insertions(+), 156 deletions(-) diff --git a/tests/performance/add_perf128.c b/tests/performance/add_perf128.c index 9c41964..60d7bf1 100644 --- a/tests/performance/add_perf128.c +++ b/tests/performance/add_perf128.c @@ -1,6 +1,4 @@ #include -#include -#include #include #include "biguint128.h" @@ -9,13 +7,16 @@ // ### Constraints and default values -#define MAX_LEVELS 8U -#define DEFAULT_LEVELS 3U -#define MAX_LOOPS (1<<28) // 256M loops -#define DEFAULT_LOOPS (1<<26) // 64M loops #define BUFLEN 40 // for full function names -#define INC_A 37U -#define INC_B 29U +const StandardConstraints LIMITS = { + 8, + (1<<28) // 256M loops +}; +const StandardArgs ARGS_DEFAULT = INIT_FUN2ARGS( + (1<<26), // 64M loops + 3U, + 37U, + 29U); // ### Local types typedef enum { @@ -42,20 +43,13 @@ const char *funname[]={ }; const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]); -const StandardArgs ARGS_DEFAULT = { - DEFAULT_LOOPS, false, false, - DEFAULT_LEVELS, -1, -1, - INC_A, INC_B, - -1, 0 -}; - // ### Internal functions static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int fun, const StandardArgs *args) { 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 + BigUInt128 *procref = (fun & 1) ? &a : &res; // note, every second function is an assignment operation clock_t t0, t1; char fnamebuf[BUFLEN]; @@ -92,5 +86,5 @@ static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int f // ### Main function int main(int argc, const char *argv[]) { - return fun2_main(argc, argv, 128, ARGS_DEFAULT, MAX_LEVELS, MAX_LOOPS, fun_n, funname, &exec_function_loop_); + return fun2_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_); } diff --git a/tests/performance/div1000_perf128.c b/tests/performance/div1000_perf128.c index 3253e35..f156341 100644 --- a/tests/performance/div1000_perf128.c +++ b/tests/performance/div1000_perf128.c @@ -1,54 +1,53 @@ -#include -#include -#include #include #include "biguint128.h" +#include "perf_common.h" #include "perf_common128.h" -#define LOOPS (1<<20) // 1M loops -#define UINT_BITS (8U * sizeof(UInt)) +const StandardConstraints LIMITS = { + 8, + (1<<26) // 64M loops +}; +const StandardArgs ARGS_DEFAULT = INIT_FUN1ARGS( + (1<<20), // 1M loops + 3U, + 29U); typedef enum { VARIANT_DIV_X_1000, VARIANT_DIV1000_X } Div1000Variant; -void exec_div1000(const BigUInt128 *ainit, const BigUInt128 *astep, Div1000Variant v) { +// ### Constants +const char *funname[] = { + "div(x,1000)", + "div1000(x)" +}; +const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]); + +static void exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args) { + 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); - BigUInt128 bx = biguint128_ctor_copy(ainit); - BigUInt128 bsum = biguint128_ctor_default(); + BigUIntPair128 res; t0 = clock(); - for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { - BigUIntPair128 res = (v==VARIANT_DIV1000_X)? - biguint128_div1000(&bx): - biguint128_div(&bx, &bdiv); - biguint128_add_assign(&bsum, &res.first); - biguint128_add_assign(&bx, astep); + 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]); + biguint128_add_tiny(&a, (UInt)args->diff_a); } t1 = clock(); - print_exec_summary(t0, t1, v==VARIANT_DIV1000_X?"div1000(x)":"div(x,1000)", loop_cnt, &bsum, 1); + print_exec_summary(t0, t1, funname[fun], loop_cnt, &chkval, 1); } -int main() { - PerfTestInitValues b = get_std_initvalues(); - BigUInt128 bstep = biguint128_value_of_uint(29); - Div1000Variant variant[] = { - VARIANT_DIV_X_1000, - VARIANT_DIV1000_X - }; - - for (int i=0; i<3; ++i) { - fprintf(stdout, "*** Dividing %s numbers ***\n", b.name[i]); - for (int j=0; j<2; ++j) { - exec_div1000(&b.val[i], &bstep, variant[j]); - } - } - - return 0; +int main(int argc, const char *argv[]) { + return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_); } diff --git a/tests/performance/div10_perf128.c b/tests/performance/div10_perf128.c index 5568d59..9d71254 100644 --- a/tests/performance/div10_perf128.c +++ b/tests/performance/div10_perf128.c @@ -1,12 +1,18 @@ -#include -#include -#include #include #include "biguint128.h" +#include "perf_common.h" #include "perf_common128.h" -#define LOOPS (1<<20) // 1M loops +// ### Constraints and default values +const StandardConstraints LIMITS = { + 8, + (1<<26) // 64M loops +}; +const StandardArgs ARGS_DEFAULT = INIT_FUN1ARGS( + (1<<20), // 1M loops + 3U, + 29U); typedef enum { VARIANT_DIV_X_10, @@ -15,57 +21,53 @@ typedef enum { VARIANT_DIV10_X } Div10Variant; -void exec_div10(const BigUInt128 *ainit, const BigUInt128 *astep, Div10Variant v) { +// ### Constants +const char *funname[] = { + "div(x,10)", + "d1000(m100(x))", + "div30(mul3(x))", + "div10(x)" +}; + +static void exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args) { + 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; - BigUInt128 bdiv = biguint128_value_of_uint(10); - BigUInt128 bx = biguint128_ctor_copy(ainit); - BigUInt128 bsum = biguint128_ctor_default(); - BigUInt128 res0, res; - t0 = clock(); - for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { - if (v == VARIANT_DIV_X_10) { - res = biguint128_div(&bx, &bdiv).first; - } else if (v == VARIANT_DIV1000_MUL100_X){ - res0 = biguint128_mul100(&bx); - res = biguint128_div1000(&res0).first; - } else if (v == VARIANT_DIV30_MUL3_X){ - res0 = biguint128_mul3(&bx); - res = biguint128_div30(&res0).first; + for (loop_cnt = 0; loop_cnt < args->loops; ++loop_cnt) { + if (fun == VARIANT_DIV_X_10) { + res = biguint128_div(&a, &bdiv); + } else if (fun == VARIANT_DIV1000_MUL100_X) { + res0 = biguint128_mul100(&a); + res = biguint128_div1000(&res0); + res.second.dat[0]/=100; + } else if (fun == VARIANT_DIV30_MUL3_X) { + res0 = biguint128_mul3(&a); + res = biguint128_div30(&res0); + res.second.dat[0]/=3; } else { - res = biguint128_div10(&bx).first; + rest = biguint128_div10(&a); } - biguint128_add_assign(&bsum, &res); - biguint128_add_assign(&bx, astep); + process_result_v1(procref1, &chkval[0].dat[0]); + process_result_v3(procref2, &chkval[1].dat[0]); + biguint128_add_tiny(&a, (UInt) args->diff_a); } t1 = clock(); - print_exec_summary(t0, t1, - v == VARIANT_DIV_X_10 ? "div(x,10)" : - v == VARIANT_DIV1000_MUL100_X ? "div1K(m100(x))" : - v == VARIANT_DIV30_MUL3_X ? "div30(mul3(x))": - "div10(x)", - loop_cnt, &bsum, 1); + print_exec_summary(t0, t1, funname[fun], loop_cnt, chkval, 2); } -int main() { - PerfTestInitValues b = get_std_initvalues(); - BigUInt128 bstep = biguint128_value_of_uint(29); - Div10Variant variant[] = { - VARIANT_DIV_X_10, - VARIANT_DIV1000_MUL100_X, - VARIANT_DIV30_MUL3_X, - VARIANT_DIV10_X - }; - - for (int i=0; i<3; ++i) { - fprintf(stdout, "*** Dividing %s numbers ***\n", b.name[i]); - for (int j=0; j< sizeof(variant)/sizeof(variant[0]); ++j) { - exec_div10(&b.val[i], &bstep, variant[j]); - } - } - - return 0; +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_); } diff --git a/tests/performance/mul_perf128.c b/tests/performance/mul_perf128.c index 5eaf2cb..0644e7d 100644 --- a/tests/performance/mul_perf128.c +++ b/tests/performance/mul_perf128.c @@ -1,6 +1,3 @@ -#include -#include -#include #include #include "biguint128.h" @@ -9,13 +6,15 @@ // ### Constraints and default values -#define MAX_LEVELS 8U -#define DEFAULT_LEVELS 3U -#define MAX_LOOPS (1<<26) // 64M loops -#define DEFAULT_LOOPS (1<<20) // 1M loops -#define BUFLEN 40 // for full function names -#define INC_A 37U -#define INC_B 29U +const StandardConstraints LIMITS = { + 8, + (1<<26) // 64M loops +}; +const StandardArgs ARGS_DEFAULT = INIT_FUN2ARGS( + (1<<20), // 1M loops + 3U, + 37U, + 29U); // ### Local types typedef enum { @@ -32,13 +31,6 @@ const char *funname[]={ }; const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]); -const StandardArgs ARGS_DEFAULT = { - DEFAULT_LOOPS, false, false, - DEFAULT_LEVELS, -1, -1, - INC_A, INC_B, - -1, 0 -}; - // ### Internal functions static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int fun, const StandardArgs *args) { @@ -47,10 +39,9 @@ static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int f 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; + BigUInt128 *procref1 = fun == FUN_MUL ? &res : &resp.first; + BigUInt128 *procref2 = fun == FUN_MUL ? &res : &resp.second; clock_t t0, t1; - char fnamebuf[BUFLEN]; t0 = clock(); for (unsigned int i = 0; i < args->loops; ++i) { @@ -66,11 +57,10 @@ static void exec_function_loop_(unsigned int ai, unsigned int bi, unsigned int f inc_operands_v1(&a, &b, (UInt) args->diff_a, (UInt) 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); + print_exec_summary(t0, t1, funname[fun], args->loops, &chkval, 1); } // ### Main function int main(int argc, const char *argv[]) { - return fun2_main(argc, argv, 128, ARGS_DEFAULT, MAX_LEVELS, MAX_LOOPS, fun_n, funname, &exec_function_loop_); + return fun2_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_); } diff --git a/tests/performance/perf_common.c b/tests/performance/perf_common.c index b68633d..cf3ebc6 100644 --- a/tests/performance/perf_common.c +++ b/tests/performance/perf_common.c @@ -94,7 +94,7 @@ void print_help_all(const char *prgname, unsigned int bits, unsigned int argmask static inline int check_args_(const char *prgname, StandardArgs *args, unsigned int bits, - unsigned int max_levels, unsigned int max_loops, + const StandardConstraints *max, unsigned int fun_n, const char *funname[], unsigned int argmask) { if (args->help) { @@ -105,28 +105,27 @@ static inline int check_args_(const char *prgname, StandardArgs *args, print_help_all(prgname, bits, argmask, fun_n, funname); return 1; } - if (max_levels < args->levels) { - fprintf(stderr, "The maximal number of levels is %u.\n", max_levels); - args->levels = max_levels; + if (max->levels < args->levels) { + fprintf(stderr, "The maximal number of levels is %u.\n", max->levels); + args->levels = max->levels; } if (args->levels < 1) { fprintf(stderr, "The minimal number of levels is 1.\n"); args->levels = 1; } - if (max_loops < args->loops) { - fprintf(stderr, "The maximal number of looops is %u.\n", max_loops); - args->loops = max_loops; + if (max->loops < args->loops) { + fprintf(stderr, "The maximal number of looops is %u.\n", max->loops); + args->loops = max->loops; } return 0; } int fun2_main(int argc, const char *argv[], - unsigned int bits, const StandardArgs args_init, - unsigned int max_levels, unsigned int max_loops, + 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)) { StandardArgs args = parse_args(argc, argv, args_init); - int check_res = check_args_(argv[0], &args, bits, max_levels, max_loops, fun_n, funname, -1); + int check_res = check_args_(argv[0], &args, bits, max, fun_n, funname, -1); if (check_res) return check_res; for (unsigned int ai = 0; ai +typedef struct { + unsigned int levels; + unsigned int loops; +} StandardConstraints; + typedef struct { unsigned int loops; bool error; @@ -25,17 +30,18 @@ typedef struct { #define ARGMASK_FEXMASK 128U #define ARGMASK_ALL 255U +#define INIT_FUN1ARGS(LOOPS,LEVELS,INCA) (StandardArgs){LOOPS, false, false, LEVELS, -1, 0, INCA, 0, -1, 0} +#define INIT_FUN2ARGS(LOOPS,LEVELS,INCA,INCB) (StandardArgs){LOOPS, false, false, LEVELS, -1, -1, INCA, INCB, -1, 0} + StandardArgs parse_args(int argc, const char *argv[], const StandardArgs res_init); void print_help(const char *prgname, unsigned int argmask); void print_help_all(const char *prgname, unsigned int bits, unsigned int argmask, unsigned int fun_n, const char *funname[]); int fun2_main(int argc, const char *argv[], - unsigned int bits, const StandardArgs args_init, - unsigned int max_levels, unsigned int max_loops, + 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)); int fun1_main(int argc, const char *argv[], - unsigned int bits, const StandardArgs args_init, - unsigned int max_levels, unsigned int max_loops, + 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)); diff --git a/tests/performance/perf_common128.h b/tests/performance/perf_common128.h index 9c9bd7c..5238cf6 100644 --- a/tests/performance/perf_common128.h +++ b/tests/performance/perf_common128.h @@ -25,7 +25,7 @@ static inline void print_exec_summary(clock_t t_begin, clock_t t_end, const char char buf[DEC_BIGUINTLEN]; print_exec_time(t_begin, t_end, op, cnt); for (int i=0; i: statistics. */ -#include -#include -#include #include #include "biguint128.h" @@ -18,14 +15,15 @@ // ### Constraints and default values -#define MAX_LEVELS 8U -#define DEFAULT_LEVELS 3U -#define MAX_LOOPS (1<<20) // 1M loops -#define DEFAULT_LOOPS (1<<17) // 128K loops #define BUFLEN (3*128/10)+10 // More than the approx. max. usage of 128 bit long dec string -#define FBUFLEN 40 // for full function names -#define INC_A 37U -#define INC_B 29U +const StandardConstraints LIMITS = { + 8, + (1<<20) // 1M loops +}; +const StandardArgs ARGS_DEFAULT = INIT_FUN1ARGS( + (1<<17), // 128K loops + 3U, + 37U); // ### Local types typedef enum { @@ -40,13 +38,6 @@ const char *funname[]={ }; const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]); -const StandardArgs ARGS_DEFAULT = { - DEFAULT_LOOPS, false, false, - DEFAULT_LEVELS, -1, -1, - INC_A, INC_B, - -1, 0 -}; - // ### Internal functions static void exec_function_loop_(unsigned int ai, unsigned int fun, const StandardArgs *args) { BigUInt128 a = get_value_by_level(ai, args->levels); @@ -54,7 +45,6 @@ static void exec_function_loop_(unsigned int ai, unsigned int fun, const Standar char pbuf[BUFLEN + 1]; buint_size_t plen; clock_t t0, t1; - char fnamebuf[FBUFLEN]; t0 = clock(); for (unsigned int i = 0; i < args->loops; ++i) { @@ -67,11 +57,10 @@ static void exec_function_loop_(unsigned int ai, unsigned int fun, const Standar biguint128_add_tiny(&a, (UInt)args->diff_a); } t1 = clock(); - snprintf(fnamebuf, FBUFLEN, "%s + 2*add_tiny(C)", funname[fun]); - print_exec_summary(t0, t1, fnamebuf, args->loops, &chkval, 1); + print_exec_summary(t0, t1, funname[fun], args->loops, &chkval, 1); } // ### Main function int main(int argc, const char *argv[]) { - return fun1_main(argc, argv, 128, ARGS_DEFAULT, MAX_LEVELS, MAX_LOOPS, fun_n, funname, &exec_function_loop_); + return fun1_main(argc, argv, 128, ARGS_DEFAULT, &LIMITS, fun_n, funname, &exec_function_loop_); }