diff --git a/benchmarks/bench_common.nim b/benchmarks/bench_common.nim new file mode 100644 index 000000000..8734fb4c4 --- /dev/null +++ b/benchmarks/bench_common.nim @@ -0,0 +1,37 @@ +import random, times, stats, strformat, math + +proc warmup*() = + # Warmup - make sure cpu is on max perf + let start = cpuTime() + var foo = 123 + for i in 0 ..< 300_000_000: + foo += i*i mod 456 + foo = foo mod 789 + + # Compiler shouldn't optimize away the results as cpuTime rely on sideeffects + let stop = cpuTime() + echo &"Warmup: {stop - start:>4.4f} s, result {foo} (displayed to avoid compiler optimizing warmup away)" + +template printStats*(experiment_name: string, compute_result: typed) {.dirty.} = + echo "\n" & experiment_name + echo &"Collected {stats.n} samples in {global_stop - global_start:>4.3f} seconds" + echo &"Average time: {stats.mean * 1000 :>4.3f} ms" + echo &"Stddev time: {stats.standardDeviationS * 1000 :>4.3f} ms" + echo &"Min time: {stats.min * 1000 :>4.3f} ms" + echo &"Max time: {stats.max * 1000 :>4.3f} ms" + echo &"Theoretical perf: {a.size.float / (float(10^6) * stats.mean):>4.3f} MFLOP/s" + echo "\nDisplay computation result to make sure it's not optimized away" + echo compute_result # Prevents compiler from optimizing stuff away + +template bench*(name: string, compute_result: typed, body: untyped) {.dirty.}= + block: # Actual bench + var stats: RunningStat + let global_start = cpuTime() + for _ in 0 ..< nb_samples: + let start = cpuTime() + block: + body + let stop = cpuTime() + stats.push stop - start + let global_stop = cpuTime() + printStats(name, compute_result)