FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Sine algorithm used by D?

 
Post new topic   Reply to topic     Forum Index -> General
View previous topic :: View next topic  
Author Message
pqnelson



Joined: 03 Jun 2007
Posts: 13
Location: Davis

PostPosted: Mon Sep 22, 2008 5:57 pm    Post subject: Sine algorithm used by D? Reply with quote

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
View user's profile Send private message AIM Address
Jeff



Joined: 04 Sep 2008
Posts: 3

PostPosted: Mon Sep 22, 2008 9:24 pm    Post subject: Reply with quote

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
View user's profile Send private message
pqnelson



Joined: 03 Jun 2007
Posts: 13
Location: Davis

PostPosted: Tue Sep 23, 2008 3:50 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
csauls



Joined: 27 Mar 2004
Posts: 278

PostPosted: Tue Sep 23, 2008 10:51 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address Yahoo Messenger
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> General All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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