DMD2 out parameters

Pete nospam at mailinator.com
Thu Dec 23 08:02:00 PST 2010


Hi,

I'm not sure if this is already a widely known phenomenon but I ran across a
little gotcha yesterday regarding floating point out parameters using DMD2.

A year or so ago I wrote a ray tracer using DMD1. A few months ago I tried
compiling and running it using DMD2. It was 50% slower. This disappointed me
so much that I stopped using D2 until about a week ago. I spent a few hours
yesterday investigating why the D2 version of the code was so much worse than
the D1 version. After some head scratching and use of -profile and objconv, I
eventually managed to isolate the problem. It boiled down to this example:

float f;
func(f);

void func(out float ff) {
ff = 1;
}

This use of 'out' causes func to execute in around 250 ticks on DMD2. Change
'out' to 'ref' and it takes around 10 ticks (the same time as the 'out'
version executes on DMD1). If you initialise f to 0 before calling func then
it all works quickly again which makes me wonder whether it's some strange
DMD2 nan/fpu exceptions quirk which may be documented somewhere?? When I
looked at the generated assembly I saw that both DMD1 and DMD2 seem to
generate the same thing (using -O -inline - release):

func  LABEL NEAR
push    ebp
mov     ebp, esp
push    eax       // eax = ptr to ff
fld     dword ptr [_nan]
fstp    dword ptr [eax]
fld     dword ptr [_one]
fstp    dword ptr [eax]

mov     esp, ebp
pop     ebp
ret

Now this code looks ok if you ignore the fact that 'ff' is being written to
twice. And the strange seemingly redundant push of EAX.

Has anyone else come across this and if so is it a bug? I'm also interested in
people's thoughts on the strange code gen.

My D2 version is now running faster than the old D1 version by the way :)

Regards,
Pete.


More information about the Digitalmars-d-learn mailing list