aboutsummaryrefslogtreecommitdiff
path: root/Math_Test.jai
diff options
context:
space:
mode:
Diffstat (limited to 'Math_Test.jai')
-rw-r--r--Math_Test.jai187
1 files changed, 106 insertions, 81 deletions
diff --git a/Math_Test.jai b/Math_Test.jai
index 8f3dce1..efc687c 100644
--- a/Math_Test.jai
+++ b/Math_Test.jai
@@ -8,7 +8,10 @@
main :: () {
- write_strings("=====================\n", "--- Test Math_Ext ---\n");
+ write_strings(
+ "#========================#\n",
+ "# Unit tests #\n"
+ );
test_op :: (operation: string, x: $Tx, y: $Ty, result: $Tr, type: Type, saturated: bool, remainder: Tr = 0) -> errors_found: int #expand {
@@ -18,13 +21,13 @@ main :: () {
if operation != "div" {
TEST_CALL :: #string DONE
t_result, t_saturated := OP(cast(Tx)x, cast(Ty)y);
- print("%_%(%, %) = %0%0\n", operation, type, x, y, result, ifx saturated then " : saturated");
+ if result != t_result print("%_%(%, %) = %0%0\n", operation, type, x, y, result, ifx saturated then " : saturated");
DONE
str = replace(TEST_CALL, "OP", operation);
} else {
TEST_CALL :: #string DONE
t_result, t_remainder, t_saturated := OP(cast(Tx)x, cast(Ty)y);
- print("%_%(%, %) = % + %0%0\n", operation, type, x, y, result, remainder, ifx saturated then " : saturated");
+ if result != t_result print("%_%(%, %) = % + %0%0\n", operation, type, x, y, result, remainder, ifx saturated then " : saturated");
DONE
str = replace(TEST_CALL, "OP", operation);
}
@@ -155,15 +158,25 @@ main :: () {
if errors > 0 print("# Found % %!\n", errors, ifx errors == 1 then "error" else "errors"); else print(" No errors found.\n");
- performance_test :: (operation: string, $type: Type) -> ops_size: s64, time_gen: Apollo_Time, time_asm: Apollo_Time #expand {
+ write_strings(
+ "#========================#\n",
+ "# Benchmarks #\n"
+ );
+
+ #import "Random";
+ performance_test :: ($operation: string, $type: Type, print_result: bool = true) -> ops_per_us_gen: float, ops_per_us_asm: float {
- SIZE :: 12000;
+ NUM_TESTS :: 500;
+ SIZE_DATA :: 12000; // Keep it below cache size.
+ best_gen := 0.0;
+ best_asm := 0.0;
+
numbers_x: [..] type;
numbers_y: [..] type;
- numbers_zgen: [SIZE] type;
- numbers_zasm: [SIZE] type;
- array_reserve(*numbers_x, SIZE);
- array_reserve(*numbers_y, SIZE);
+ numbers_zgen: [SIZE_DATA] type;
+ numbers_zasm: [SIZE_DATA] type;
+ array_reserve(*numbers_x, SIZE_DATA);
+ array_reserve(*numbers_y, SIZE_DATA);
#if type == u8 { MIN :: 0; MAX :: U8_MAX; }
#if type == u16 { MIN :: 0; MAX :: U16_MAX; }
@@ -173,9 +186,8 @@ main :: () {
#if type == s16 { MIN :: S16_MIN; MAX :: S16_MAX; }
#if type == s32 { MIN :: S32_MIN; MAX :: S32_MAX; }
#if type == s64 { MIN :: S64_MIN; MAX :: S64_MAX; }
-
- for 0..SIZE-1 {
-
+
+ for 0..SIZE_DATA-1 {
x := cast(type) random_get_within_range(xx MIN, xx MAX);
y := cast(type) random_get_within_range(xx MIN, xx MAX);
if y == 0 && operation == "div" {
@@ -184,79 +196,92 @@ main :: () {
array_add(*numbers_x, x);
array_add(*numbers_y, y);
}
+
+ for 0..NUM_TESTS-1 {
+
+ time_gen := current_time_monotonic();
+ for 0..SIZE_DATA-1 #insert #run replace("numbers_zgen[it] = OP(numbers_x[it], numbers_y[it], true);", "OP", operation);
+ time_gen = current_time_monotonic() - time_gen;
- control_gen: type;
- control_asm: type;
-
- control_gen = 1;
- time_gen := current_time_monotonic();
- for 0..SIZE-1 #insert #run replace("numbers_zgen[it] = OP(numbers_x[it], numbers_y[it], true);", "OP", operation);
- time_gen = current_time_monotonic() - time_gen;
-
- control_asm = 1;
- time_asm := current_time_monotonic();
- for 0..SIZE-1 #insert #run replace("numbers_zasm[it] = OP(numbers_x[it], numbers_y[it]);", "OP", operation);
- time_asm = current_time_monotonic() - time_asm;
+ time_asm := current_time_monotonic();
+ for 0..SIZE_DATA-1 #insert #run replace("numbers_zasm[it] = OP(numbers_x[it], numbers_y[it]);", "OP", operation);
+ time_asm = current_time_monotonic() - time_asm;
- for 0..SIZE-1 assert(numbers_zgen[it] == numbers_zasm[it]);
+ for 0..SIZE_DATA-1 assert(numbers_zgen[it] == numbers_zasm[it]);
- return SIZE, time_gen, time_asm;
- }
-
- // Performance test.
- #import "Random";
- best_gen: float;
- best_asm: float;
-
- TEST_STR :: #string DONE
- best_gen = 0;
- best_asm = 0;
- for 0..500 {
- size, time_gen, time_asm := performance_test("OP", TYPE);
- perf_gen := cast(float)size/cast(float)to_microseconds(time_gen);
- perf_asm := cast(float)size/cast(float)to_microseconds(time_asm);
+ perf_gen := cast(float)SIZE_DATA/cast(float)to_microseconds(time_gen);
+ perf_asm := cast(float)SIZE_DATA/cast(float)to_microseconds(time_asm);
best_gen = max(best_gen, perf_gen);
best_asm = max(best_asm, perf_asm);
}
- print("% : %\n generic : %\n asm : %\n", "OP", TYPE, best_gen, best_asm);
- DONE
-
- print("----- op : ops/usec ---\n");
- types :: string.["s8", "s16", "s32", "s64"];
-
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "s8");
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "s16");
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "s32");
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "s64");
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "u8");
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "u16");
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "u32");
- #insert #run replace(replace(TEST_STR, "OP", "add"), "TYPE", "u64");
-
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "s8");
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "s16");
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "s32");
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "s64");
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "u8");
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "u16");
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "u32");
- #insert #run replace(replace(TEST_STR, "OP", "sub"), "TYPE", "u64");
-
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "s8");
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "s16");
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "s32");
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "s64");
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "u8");
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "u16");
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "u32");
- #insert #run replace(replace(TEST_STR, "OP", "mul"), "TYPE", "u64");
-
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "s8");
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "s16");
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "s32");
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "s64");
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "u8");
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "u16");
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "u32");
- #insert #run replace(replace(TEST_STR, "OP", "div"), "TYPE", "u64");
+
+ if print_result {
+ if type == s8 || type == u8 write_string(" ");
+ print("% | % | % |\n", type, best_gen, best_asm);
+ }
+ return best_gen, best_asm;
+ }
+
+ ff := context.print_style.default_format_float;
+ ff.zero_removal = .NO;
+ ff.width = 7;
+ ff.trailing_width = 1;
+ context.print_style.default_format_float = ff;
+
+ write_strings(
+ " # (ops / usec) #\n",
+ " | generic | x64 asm |\n"
+ );
+
+ write_strings(
+ "--- | ----------------- |\n",
+ " | add |\n"
+ );
+ performance_test("add", u8);
+ performance_test("add", u16);
+ performance_test("add", u32);
+ performance_test("add", u64);
+ performance_test("add", s8);
+ performance_test("add", s16);
+ performance_test("add", s32);
+ performance_test("add", s64);
+
+ write_strings(
+ "--- | ----------------- |\n",
+ " | sub |\n"
+ );
+ performance_test("sub", u8);
+ performance_test("sub", u16);
+ performance_test("sub", u32);
+ performance_test("sub", u64);
+ performance_test("sub", s8);
+ performance_test("sub", s16);
+ performance_test("sub", s32);
+ performance_test("sub", s64);
+
+ write_strings(
+ "--- | ----------------- |\n",
+ " | mul |\n"
+ );
+ performance_test("mul", u8);
+ performance_test("mul", u16);
+ performance_test("mul", u32);
+ performance_test("mul", u64);
+ performance_test("mul", s8);
+ performance_test("mul", s16);
+ performance_test("mul", s32);
+ performance_test("mul", s64);
+
+ write_strings(
+ "--- | ----------------- |\n",
+ " | div |\n"
+ );
+ performance_test("div", u8);
+ performance_test("div", u16);
+ performance_test("div", u32);
+ performance_test("div", u64);
+ performance_test("div", s8);
+ performance_test("div", s16);
+ performance_test("div", s32);
+ performance_test("div", s64);
}