View previous topic :: View next topic |
Author |
Message |
pqnelson
Joined: 03 Jun 2007 Posts: 13 Location: Davis
|
Posted: Mon Sep 22, 2008 5:57 pm Post subject: Sine algorithm used by D? |
|
|
Hello,
I am doing some floating point computations, and I noticed when working with the GNU C compiler (the *GCC*) it gives me garbage answers for the sine of a number (-1.50901e+14 if you'd like to know...). When working with the GNU D Compiler, it gives me a sensible answer (-4.6421796528334225E-14 to be more exact...).
I'm just wondering what algorithm is used for the sine function in the GNU D Compiler (I assume the Mars D Compiler is also using the same algorithm...), for the sake of curiosity.
Thanks! |
|
Back to top |
|
|
Jeff
Joined: 04 Sep 2008 Posts: 3
|
Posted: Mon Sep 22, 2008 9:24 pm Post subject: |
|
|
I would assume that the sine function is calculated using the FPU instruction for it. Of course that doesn't explain why different compilers are getting different results. A bug perhaps? |
|
Back to top |
|
|
pqnelson
Joined: 03 Jun 2007 Posts: 13 Location: Davis
|
Posted: Tue Sep 23, 2008 3:50 pm Post subject: |
|
|
Upon closer examination, I believe you are right. My detective work is as follows: here is my program in D
Code: | /* foo.d */
import std.stdio;
import std.math;
void main()
{
real x;
x = 1.60535070439173075510552735E+06;
writef("%.16E\n",sin(x));
} |
Then I simply typed $ gdc -fverbose-asm -S foo.d to get the resulting assembly file:
Code: | .file "foo.d"
# GNU D version 4.2.3 20080225 (prerelease gdc 0.25 20071215, using dmd 1.022) (Ubuntu 0.25-4.2.3-2ubuntu2) (i486-linux-gnu)
# compiled by GNU C version 4.2.3 20080225 (prerelease gdc 0.25 20071215, using dmd 1.022) (Ubuntu 0.25-4.2.3-2ubuntu2).
# GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
# options passed: -mtune=generic -auxbase -fverbose-asm
# options enabled: -falign-loops -fargument-alias -fbounds-check
# -fbranch-count-reg -fcommon -fearly-inlining
# -feliminate-unused-debug-types -fexceptions -ffunction-cse -fgcse-lm
# -fident -finline-functions-called-once -fivopts -fkeep-static-consts
# -fleading-underscore -fmath-errno -fmove-loop-invariants
# -fpcc-struct-return -fpeephole -fsched-interblock -fsched-spec
# -fsched-stalled-insns-dep -fshow-column -fsplit-ivs-in-unroller
# -ftoplevel-reorder -ftrapping-math -ftree-loop-im -ftree-loop-ivcanon
# -ftree-loop-optimize -ftree-vect-loop-version -fverbose-asm
# -fzero-initialized-in-bss -m32 -m80387 -m96bit-long-double
# -maccumulate-outgoing-args -malign-stringops -mfancy-math-387
# -mfp-ret-in-387 -mglibc -mieee-fp -mno-red-zone -mpush-args
# -mtls-direct-seg-refs
.section .rodata
.LC2:
.string "%.16E\n"
.text
.globl _Dmain
.type _Dmain, @function
_Dmain:
.LFB2:
leal 4(%esp), %ecx #,
.LCFI0:
andl $-16, %esp #,
pushl -4(%ecx) #
.LCFI1:
pushl %ebp #
.LCFI2:
movl %esp, %ebp #,
.LCFI3:
pushl %ecx #
.LCFI4:
subl $68, %esp #,
.LCFI5:
movl $0, %eax #,
movl $-1073741824, %edx #,
movl $32767, %ecx #,
movl %eax, -24(%ebp) #, x
movl %edx, -20(%ebp) #, x
movl %ecx, -16(%ebp) #, x
movl $-1742620332, %eax #,
movl $-1007209054, %edx #,
movl $16403, %ecx #,
movl %eax, -24(%ebp) #, x
movl %edx, -20(%ebp) #, x
movl %ecx, -16(%ebp) #, x
movl -24(%ebp), %eax # x,
movl -20(%ebp), %edx # x,
movl -16(%ebp), %ecx # x,
movl %eax, (%esp) #,
[b] movl %edx, 4(%esp) #,
movl %ecx, 8(%esp) #,
call sinl #
movl $6, -32(%ebp) #, D.1135
movl $.LC2, -28(%ebp) #, D.1135
[/b] movl -28(%ebp), %eax # D.1135, D.1136
movl -32(%ebp), %edx # D.1135, D.1137
fstpt 12(%esp) #
movl %eax, 8(%esp) # D.1136,
movl %edx, 4(%esp) # D.1137,
movl $_D14TypeInfo_B3Aae6__initZ, (%esp) #,
call _D3std5stdio6writefFYv #
movl $0, %eax #, D.1138
addl $68, %esp #,
popl %ecx #
popl %ebp #
leal -4(%ecx), %esp #,
ret
.LFE2:
.size _Dmain, .-_Dmain
.globl __gdc_personality_v0
.data
.type ___s.1145, @object
.size ___s.1145, 8
___s.1145:
# <anonymous>:
.long _D11TypeInfo_Aa6__initZ
# <anonymous>:
.long _D10TypeInfo_e6__initZ
.weak _D14TypeInfo_B3Aae6__initZ
.section .data._D14TypeInfo_B3Aae6__initZ,"awG",@progbits,_D14TypeInfo_B3Aae6__initZ,comdat
.align 4
.type _D14TypeInfo_B3Aae6__initZ, @object
.size _D14TypeInfo_B3Aae6__initZ, 8
_D14TypeInfo_B3Aae6__initZ:
# <anonymous>:
.long _D14TypeInfo_Tuple6__vtblZ
# <anonymous>:
.long 0
# <anonymous>:
.long 2
# <anonymous>:
.long ___s.1145
.globl _D3foo12__ModuleInfoZ
.section .rodata
.LC4:
.string "foo"
.data
.align 4
.type _D3foo12__ModuleInfoZ, @object
.size _D3foo12__ModuleInfoZ, 8
_D3foo12__ModuleInfoZ:
# <anonymous>:
.long 0
# <anonymous>:
.long 0
# <anonymous>:
.long 3
# <anonymous>:
.long .LC4
# <anonymous>:
.long 2
# <anonymous>:
.long _D3foo12__ModuleInfoZ+48
# <anonymous>:
.long 0
# <anonymous>:
.long 0
# <anonymous>:
.long 0
# <anonymous>:
.long 0
# <anonymous>:
.long 0
# <anonymous>:
.long 0
# <anonymous>:
.long _D3std5stdio12__ModuleInfoZ
# <anonymous>:
.long _D3std4math12__ModuleInfoZ
.align 4
.type __mod_ref.1167, @object
.size __mod_ref.1167, 8
__mod_ref.1167:
# next:
.long 0
# mod:
.long _D3foo12__ModuleInfoZ
.text
.type _D3foo9__modinitFZv, @function
_D3foo9__modinitFZv:
.LFB3:
pushl %ebp #
.LCFI6:
movl %esp, %ebp #,
.LCFI7:
movl _Dmodule_ref, %eax # _Dmodule_ref, _Dmodule_ref.0
movl %eax, __mod_ref.1167 # _Dmodule_ref.0, __mod_ref.next
movl $__mod_ref.1167, _Dmodule_ref #, _Dmodule_ref
popl %ebp #
ret
.LFE3:
.size _D3foo9__modinitFZv, .-_D3foo9__modinitFZv
.section .ctors,"aw",@progbits
.align 4
.long _D3foo9__modinitFZv
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zP"
.uleb128 0x1
.sleb128 -4
.byte 0x8
.uleb128 0x5
.byte 0x0
.long __gdc_personality_v0
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x88
.uleb128 0x1
.align 4
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB2
.long .LFE2-.LFB2
.uleb128 0x0
.byte 0x4
.long .LCFI0-.LFB2
.byte 0xc
.uleb128 0x1
.uleb128 0x0
.byte 0x9
.uleb128 0x4
.uleb128 0x1
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x4
.long .LCFI2-.LCFI1
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI3-.LCFI2
.byte 0xd
.uleb128 0x5
.byte 0x4
.long .LCFI4-.LCFI3
.byte 0x84
.uleb128 0x3
.align 4
.LEFDE1:
.ident "GCC: (GNU) 4.2.3 20080225 (prerelease gdc 0.25 20071215, using dmd 1.022) (Ubuntu 0.25-4.2.3-2ubuntu2)"
.section .note.GNU-stack,"",@progbits | Note the bold region is where the sine computation is performed, it uses a sinl opcode.
The underlying assumption here is that sinl is provided by the processor and not the operating system or some library! |
|
Back to top |
|
|
csauls
Joined: 27 Mar 2004 Posts: 278
|
Posted: Tue Sep 23, 2008 10:51 pm Post subject: |
|
|
The difference is most likely in the data type used; sinl() is a standard function. Phobos users should (I believe) find it in module std.c.math -- Tango users should find it in tango.stdc.math.
I note that you used the real type in the sample D, which is the 80b hardware float... did you try long double in the C version?
Edited to note: the Tango implementation of sin() (tango.math.Math) uses the fsin instruction if available, rather than call the standard function. I can't say absolutely what Phobos does, but it looks like it just calls the function. _________________ Chris Nicholson-Sauls |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|