D.gnu - Strange optimization/inlining error on gdc 0.19
The following source code displays radically different times between Method 1 and Method 2. It seems some methods don't get inlined, since the dmd build results in far more similar timings. I would be grateful for an explanation. My values: DMD with -release -inline -O: Method 1: 93ms Method 2: 94ms GDC with -s -O3 -fomit-frame-pointer -funroll-loops -finline-functions: Method 1: 450ms <-- !!!!!!!! Method 2: 87ms The code for the benchmark was: import std.cstream; import std.perf; final class Small { float value; final void set(float inval) { value=inval; } final float get() { return value; } } final class Big { Small variable; public this() { variable=new Small(); } final Small getVar() { return variable; } } int main() { Big BigThing=new Big(); Small SmallThing=new Small(); void method1(inout Big A, inout Small B) { B.set(A.getVar().get()); } void method2(inout Big A, inout Small B) { B.value=A.variable.value; } uint benchmark(void delegate(inout Big, inout Small) fn, Big A, Small B, uint loops) { PerformanceCounter pc=new PerformanceCounter; pc.start(); for (uint i=0; i<loops; ++i) fn(A, B); pc.stop(); return pc.microseconds(); } const uint looplength=10000000; uint time1=benchmark(&method1, BigThing, SmallThing, looplength); uint time2=benchmark(&method2, BigThing, SmallThing, looplength); dout.writefln("time with method 1 = ", time1); dout.writefln("time with method 2 = ", time2); return 0; }
Jul 28 2006
Just off-hand, try adding -frelease to the gdc switches. With the gdmd script you can use the same opts. as dmd and it will do that. Downs wrote:The following source code displays radically different times between Method 1 and Method 2. It seems some methods don't get inlined, since the dmd build results in far more similar timings. I would be grateful for an explanation. My values: DMD with -release -inline -O: Method 1: 93ms Method 2: 94ms GDC with -s -O3 -fomit-frame-pointer -funroll-loops -finline-functions: Method 1: 450ms <-- !!!!!!!! Method 2: 87ms The code for the benchmark was: import std.cstream; import std.perf; final class Small { float value; final void set(float inval) { value=inval; } final float get() { return value; } } final class Big { Small variable; public this() { variable=new Small(); } final Small getVar() { return variable; } } int main() { Big BigThing=new Big(); Small SmallThing=new Small(); void method1(inout Big A, inout Small B) { B.set(A.getVar().get()); } void method2(inout Big A, inout Small B) { B.value=A.variable.value; } uint benchmark(void delegate(inout Big, inout Small) fn, Big A, Small B, uint loops) { PerformanceCounter pc=new PerformanceCounter; pc.start(); for (uint i=0; i<loops; ++i) fn(A, B); pc.stop(); return pc.microseconds(); } const uint looplength=10000000; uint time1=benchmark(&method1, BigThing, SmallThing, looplength); uint time2=benchmark(&method2, BigThing, SmallThing, looplength); dout.writefln("time with method 1 = ", time1); dout.writefln("time with method 2 = ", time2); return 0; }
Jul 28 2006
Dave wrote:Just off-hand, try adding -frelease to the gdc switches. With the gdmd script you can use the same opts. as dmd and it will do that.Consider this problem solved. Thanks go to Dave for pointing out the solution. (New benchmark results: 90ms with both)
Jul 28 2006