Please rid me of this goto

John Colvin via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 23 17:26:52 PDT 2016


On Thursday, 23 June 2016 at 23:34:54 UTC, David Nadlinger wrote:
> On Thursday, 23 June 2016 at 22:08:20 UTC, Seb wrote:
>> [1] https://github.com/wilzbach/perf-d/blob/master/test_pow.d
>> [2] https://github.com/wilzbach/perf-d/blob/master/test_powi.d
>
> This is a bad way to benchmark. You are essentially testing the 
> compiler's ability to propagate your constants into the 
> benchmarking loop/hoisting the code to be benchmarked out of it.
>
> For cross-compiler tests, you should define the candidate 
> functions in a separate compilation units with an extern(C) 
> interface to inhibit any optimisations. In this case, your code 
> could e.g. be altered to:
>
> ---
> import std.math : pow;
> extern(C) long useStd(long a, long b) { return pow(a, b); }
> extern(C) long useOp(long a, long b) { return a ^^ b; }
> ---
> extern(C) long useStd(long a, long b);
> extern(C) long useOp(long a, long b);
>
> void main(string[] args)
> {
>     import std.datetime: benchmark, Duration;
>     import std.stdio: writeln, writefln;
>     import std.conv: to;
>
>     long a = 5;
>     long b = 25;
>     long l = 0;
>
>     void f0() { l += useStd(a, b); }
>     void f1() { l += useOp(a, b); }
>
>     auto rs = benchmark!(f0, f1)(100_000_000);
>
>     foreach(j,r;rs)
>     {
>         version(GNU)
>             writefln("%d %d secs %d ms", j, r.seconds(), 
> r.msecs());
>         else
>             writeln(j, " ", r.to!Duration);
>     }
>
>     // prevent any optimization
>     writeln(l);
> }
> ---
> (Keeping track of the sum is of course no longer really 
> necessary.)
>
> I get the following results:
>
> ---
> $ gdc -finline-functions -frelease -O3 -c test1.d
> $ gdc -finline-functions -frelease -O3 test.d test1.o
> $ ./a.out
> 0 0 secs 620 ms
> 1 0 secs 647 ms
> 4939766238266722816
> ---
>
> ---
> $ ldc2 -O3 -release -c test1.d
> $ ldc2 -O3 -release test.d test1.o
> $ ./test
> 0 418 ms, 895 μs, and 3 hnsecs
> 1 409 ms, 776 μs, and 1 hnsec
> 4939766238266722816
> ---
>
> ---
> $ dmd -O -release -inline -c test1.d
> $ dmd -O -release -inline test.d test1.o
> 0 637 ms, 19 μs, and 9 hnsecs
> 1 722 ms, 57 μs, and 8 hnsecs
> 4939766238266722816
> ---
>
>  — David

This is my preferred way of benchmarking as well, people often 
tell me cleverer ways but nothing gives me peace of mind like 
separate compilation without mangling!

Not wanting to pick on Seb in particular, but I see quite a lot 
of poor benchmarking on these forums from different people 
(myself included, not these days though I hope).

My biggest bugbear is actually the opposite of what you are point 
out here: people doing careful benchmarking and asm-inspection of 
small code-fragments in isolation when in reality it is always 
going to be inlined and optimised in context.


More information about the Digitalmars-d mailing list