www.digitalmars.com         C & C++   DMDScript  

D.gnu - Strange optimization/inlining error on gdc 0.19

reply Downs <default_357-line mail.yahoo.de> writes:
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
parent reply Dave <Dave_member pathlink.com> writes:
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
parent Downs <default_357-line mail.yahoo.de> writes:
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