-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ISSUE-0051]: Unified additive and multiplicative performance tests
- Loading branch information
Showing
6 changed files
with
363 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
UINT_PROGS = add_uperf | ||
BUINT128_PROGS = \ | ||
add_perf128 \ | ||
mul_perf128 \ | ||
div10_perf128 \ | ||
div1000_perf128 \ | ||
parse_perf128 \ | ||
|
@@ -13,6 +14,7 @@ CLEANFILES = | |
|
||
BUINT256_PROGS = \ | ||
add_perf256 \ | ||
mul_perf256 \ | ||
div10_perf256 \ | ||
div1000_perf256 \ | ||
parse_perf256 \ | ||
|
@@ -21,6 +23,7 @@ BUINT256_PROGS = \ | |
|
||
BUINT512_PROGS = \ | ||
add_perf512 \ | ||
mul_perf512 \ | ||
div10_perf512 \ | ||
div1000_perf512 \ | ||
parse_perf512 \ | ||
|
@@ -29,6 +32,7 @@ BUINT512_PROGS = \ | |
|
||
BUINTEXTRA_PROGS = \ | ||
add_perf@userdef_bits@ \ | ||
mul_perf@userdef_bits@ \ | ||
div10_perf@userdef_bits@ \ | ||
div1000_perf@userdef_bits@ \ | ||
parse_perf@userdef_bits@ \ | ||
|
@@ -40,13 +44,15 @@ if WITH_BIGUINT256 | |
|
||
CLEANFILES += perf_common256.h \ | ||
add_perf256.c \ | ||
mul_perf256.c \ | ||
div10_perf256.c \ | ||
div1000_perf256.c \ | ||
parse_perf256.c \ | ||
print_perf256.c \ | ||
shift_perf256.c | ||
|
||
nodist_add_perf256_SOURCES = add_perf256.c | ||
nodist_mul_perf256_SOURCES = mul_perf256.c | ||
nodist_div10_perf256_SOURCES = div10_perf256.c | ||
nodist_div1000_perf256_SOURCES = div1000_perf256.c | ||
nodist_parse_perf256_SOURCES = parse_perf256.c | ||
|
@@ -66,13 +72,15 @@ if WITH_BIGUINT512 | |
|
||
CLEANFILES += perf_common512.h \ | ||
add_perf512.c \ | ||
mul_perf512.c \ | ||
div10_perf512.c \ | ||
div1000_perf512.c \ | ||
parse_perf512.c \ | ||
print_perf512.c \ | ||
shift_perf512.c | ||
|
||
nodist_add_perf512_SOURCES = add_perf512.c | ||
nodist_mul_perf512_SOURCES = mul_perf512.c | ||
nodist_div10_perf512_SOURCES = div10_perf512.c | ||
nodist_div1000_perf512_SOURCES = div1000_perf512.c | ||
nodist_parse_perf512_SOURCES = parse_perf512.c | ||
|
@@ -92,13 +100,15 @@ if EXTRA_BITLEN | |
|
||
CLEANFILES += perf_common@[email protected] \ | ||
add_perf@[email protected] \ | ||
mul_perf@[email protected] \ | ||
div10_perf@[email protected] \ | ||
div1000_perf@[email protected] \ | ||
parse_perf@[email protected] \ | ||
print_perf@[email protected] \ | ||
shift_perf@[email protected] | ||
|
||
nodist_add_perf@userdef_bits@_SOURCES = add_perf@[email protected] | ||
nodist_mul_perf@userdef_bits@_SOURCES = mul_perf@[email protected] | ||
nodist_div10_perf@userdef_bits@_SOURCES = div10_perf@[email protected] | ||
nodist_div1000_perf@userdef_bits@_SOURCES = div1000_perf@[email protected] | ||
nodist_parse_perf@userdef_bits@_SOURCES = parse_perf@[email protected] | ||
|
@@ -114,7 +124,7 @@ if EXTRA_BITLEN | |
endif | ||
|
||
AM_CPPFLAGS = -I${top_srcdir}/src -I../../src | ||
LDADD = ../../src/libbiguint.a | ||
LDADD = perf_common.o ../../src/libbiguint.a | ||
|
||
EXTRA_DIST = perf_common128.h | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,129 +1,96 @@ | ||
#include "biguint128.h" | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <time.h> | ||
|
||
#define LOOPS (1<<26) // 64M loops | ||
#define BUFLEN 40 // for printsceen debugging | ||
#include "biguint128.h" | ||
#include "perf_common.h" | ||
#include "perf_common128.h" | ||
|
||
static void print_result(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); | ||
} | ||
|
||
int main() { | ||
BigUInt128 b0 = biguint128_ctor_default(); | ||
BigUInt128 b1 = biguint128_ctor_unit(); | ||
uint32_t loop_cnt; | ||
clock_t t0, t1; | ||
char buf[BUFLEN]; | ||
// ### 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 | ||
|
||
// #1: conventional add | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
b0 = biguint128_add(&b0, &b1); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "add", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
// ### Local types | ||
typedef enum { | ||
FUN_ADD = 0, | ||
FUN_ADD_ASGN, | ||
FUN_ADD_REPL, | ||
FUN_ADD_TINY, | ||
FUN_SUB, | ||
FUN_SUB_ASGN, | ||
FUN_SUB_REPL, | ||
FUN_SUB_TINY | ||
} AdditiveFun; | ||
|
||
// #2: add-assignment | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_add_assign(&b0, &b1); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "add-assignment", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
// ### Constants | ||
const char *funname[]={ | ||
"add", | ||
"add_assign", | ||
"add_replace", | ||
"add_tiny", | ||
"sub", | ||
"sub_assign", | ||
"sub_replace", | ||
"sub_tiny" | ||
}; | ||
const unsigned int fun_n = sizeof(funname) / sizeof(funname[0]); | ||
|
||
// #2: add-replace | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_add_replace(&b0, &b0, &b1); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "add-replace", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
const StandardArgs ARGS_DEFAULT = { | ||
DEFAULT_LOOPS, false, false, | ||
DEFAULT_LEVELS, -1, -1, | ||
INC_A, INC_B, | ||
-1, 0 | ||
}; | ||
|
||
// #3: add-assign uint as biguint | ||
{ | ||
t0 = clock(); | ||
BigUInt128 b2 = biguint128_ctor_standard(&b1.dat[0]); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_add_assign(&b0, &b2); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "add-assign uint", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
} | ||
// #4: add-tiny | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_add_tiny(&b0, b1.dat[0]); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "add-tiny", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
// ### 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 | ||
clock_t t0, t1; | ||
char fnamebuf[BUFLEN]; | ||
|
||
// #5: sub-tiny | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_sub_tiny(&b0, b1.dat[0]); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "sub-tiny", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
|
||
// #6: sub-assign uint as biguint | ||
{ | ||
t0 = clock(); | ||
BigUInt128 b2 = biguint128_ctor_standard(&b1.dat[0]); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_sub_assign(&b0, &b2); | ||
for (unsigned int i = 0; i < args->loops; ++i) { | ||
if (!(fun & 4)) { // lower 4 functions | ||
if (fun == FUN_ADD) { | ||
res = biguint128_add(&a, &b); | ||
} else if (fun == FUN_ADD_ASGN) { | ||
biguint128_add_assign(&a, &b); | ||
} else if (fun == FUN_ADD_TINY) { | ||
biguint128_add_tiny(&a, b.dat[0]); | ||
} else if (fun == FUN_ADD_REPL) { | ||
biguint128_add_replace(&res, &a, &b); | ||
} | ||
} else { // upper 4 functions | ||
if (fun == FUN_SUB) { | ||
res = biguint128_sub(&a, &b); | ||
} else if (fun == FUN_SUB_ASGN) { | ||
biguint128_sub_assign(&a, &b); | ||
} else if (fun == FUN_SUB_TINY) { | ||
biguint128_sub_tiny(&a, b.dat[0]); | ||
} else if (fun == FUN_SUB_REPL) { | ||
biguint128_sub_replace(&res, &a, &b); | ||
} | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "sub-assign uint", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
} | ||
|
||
// #7: sub-replace | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_sub_replace(&b0, &b0, &b1); | ||
process_result_v1(procref, &chkval.dat[0]); | ||
inc_operands_v1(&a, &b, args->diff_a, args->diff_b); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "sub-replace", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
|
||
// #8: sub-assignment | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
biguint128_sub_assign(&b0, &b1); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "sub-assignment", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
|
||
// #9: conventional sub | ||
t0 = clock(); | ||
for (loop_cnt = 0; loop_cnt < LOOPS; ++loop_cnt) { | ||
b0 = biguint128_sub(&b0, &b1); | ||
} | ||
t1 = clock(); | ||
print_result(t0, t1, "sub", LOOPS); | ||
buf[biguint128_print_dec(&b0, buf, BUFLEN)] = 0; | ||
fprintf(stdout, "(current sum: %s)\n", buf); | ||
snprintf(fnamebuf, BUFLEN, "%s + 2*add_tiny(C)", funname[fun]); | ||
print_exec_summary(t0, t1, fnamebuf, args->loops, &chkval, 1); | ||
} | ||
|
||
return 0; | ||
// ### 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_); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <time.h> | ||
|
||
#include "biguint128.h" | ||
#include "perf_common.h" | ||
#include "perf_common128.h" | ||
|
||
|
||
// ### 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 | ||
|
||
// ### Local types | ||
typedef enum { | ||
FUN_MUL = 0, | ||
FUN_DMUL, | ||
FUN_DIV | ||
} MultiplicativeFun; | ||
|
||
// ### Constants | ||
const char *funname[]={ | ||
"mul", | ||
"dmul", | ||
"div" | ||
}; | ||
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; | ||
BigUIntPair128 resp; | ||
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) { | ||
if (fun == FUN_MUL) { | ||
res = biguint128_mul(&a, &b); | ||
} else if (fun == FUN_DMUL) { | ||
resp = biguint128_dmul(&a, &b); | ||
} else if (fun == FUN_DIV) { | ||
resp = biguint128_div(&a, &b); | ||
} | ||
process_result_v1(procref2, &chkval.dat[0]); | ||
process_result_v1(procref1, &chkval.dat[0]); | ||
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); | ||
} | ||
|
||
// ### 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_); | ||
} |
Oops, something went wrong.