It seems like DMD doesn't optimize tail recursion very well
    pragma 
    pragma_member at pathlink.com
       
    Fri Jun  9 10:25:32 PDT 2006
    
    
  
Attached are the ASM dump of the Ack() function as outlined elsewhere in this
thread.  
I was actually suprised that the extern(C) D version of the Ack() function was
byte-for-byte identical to the plain C/CPP version of the same code.  The plain
extern(D) version was the only run that created a different routine, and hence,
the wildly different timings.
To my eye, the codegen in D is not only shorter, but more efficent.  The only
thing I'm not too sure on is the use of enter/leave instead of push/pop/mov for
maintaining up the function's stack frame.  While I have no solid evidence, I'd
be willing to bet that these two instructions are what's holding things up.
My timings are on an Intel chip.  Anyone out there with an AMD machine willing
to try this on?
- Eric
// dissasembler listing for ackd.exe 
// int Ack(int a, int b)
SUB_L00402010:
enter	0004h,00h
mov	[ebp-04h],eax
nop
nop
nop
cmp	dword ptr [ebp+08h],00000000h
jnz	L00402025
inc	eax
leave
retn	0004h
;------------------------------------------------------------------------------
L00402025:
cmp	dword ptr [ebp-04h],00000000h
jnz	L0040203E
mov	eax,[ebp+08h]
dec	eax
push	eax
mov	eax,00000001h
call	SUB_L00402010
leave
retn	0004h
;------------------------------------------------------------------------------
L0040203E:
mov	ecx,[ebp+08h]
lea	edx,[ecx-01h]
push	edx
push	ecx
mov	eax,[ebp-04h]
dec	eax
call	SUB_L00402010
call	SUB_L00402010
leave
retn	0004h
// dissasembler listing for ackd.exe 
// extern(C) int Ack(int a, int b)
SUB_L00402010:
push	ebp
mov	ebp,esp
push	ebx
nop
nop
nop
cmp	dword ptr [ebp+08h],00000000h
jnz	L00402024
mov	eax,[ebp+0Ch]
inc	eax
pop	ebx
pop	ebp
retn
;------------------------------------------------------------------------------
L00402024:
cmp	dword ptr [ebp+0Ch],00000000h
jnz	L0040203C
push	00000001h
mov	ecx,[ebp+08h]
dec	ecx
push	ecx
call	SUB_L00402010
add	esp,00000008h
pop	ebx
pop	ebp
retn
;------------------------------------------------------------------------------
L0040203C:
mov	edx,[ebp+0Ch]
dec	edx
push	edx
push	[ebp+08h]
call	SUB_L00402010
add	esp,00000008h
push	eax
mov	ebx,[ebp+08h]
dec	ebx
push	ebx
call	SUB_L00402010
add	esp,00000008h
pop	ebx
pop	ebp
retn
// dissasembler listing for ackcpp.exe 
// int Ack(int a, int b)
SUB_L00402010:
push	ebp
mov	ebp,esp
push	ebx
nop
nop
nop
cmp	dword ptr [ebp+08h],00000000h
jnz	L00402024
mov	eax,[ebp+0Ch]
inc	eax
pop	ebx
pop	ebp
retn
;------------------------------------------------------------------------------
L00402024:
cmp	dword ptr [ebp+0Ch],00000000h
jnz	L0040203C
push	00000001h
mov	ecx,[ebp+08h]
dec	ecx
push	ecx
call	SUB_L00402010
add	esp,00000008h
pop	ebx
pop	ebp
retn
;------------------------------------------------------------------------------
L0040203C:
mov	edx,[ebp+0Ch]
dec	edx
push	edx
push	[ebp+08h]
call	SUB_L00402010
add	esp,00000008h
push	eax
mov	ebx,[ebp+08h]
dec	ebx
push	ebx
call	SUB_L00402010
add	esp,00000008h
pop	ebx
pop	ebp
retn
    
    
More information about the Digitalmars-d
mailing list