Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / Floating point math gives different results when using SSE Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
elFarto

January 03, 2005, 03:57 PM

Hi,

I've been trying to re-write some methods in my simple raytracer using SSE3. Unfortunally I've hit an accuracy problem. The SSE code seems to be returning slightly different values to the normal C code. Does anyone know what could cause this?

Here's the result of the program below:

  1. A:   40.000000 5.000000 -50.000000 0.000000
  2. B:   40.000000 5.000000 -50.000000 0.000000
  3. SSE: 0.622711 0.077839 -0.778389 0.000000
  4. C:   0.622799 0.077850 -0.778499 0.000000


From what I can tell, the C method is the correct one.
I'm using gcc 3.4.2 under windows, and the command line parameters:
gcc -O2 -march=pentium4 -msse3 -o test2.exe test2.c

  1. #include <stdio.h>
  2. typedef int v4sf __attribute__ ((mode(V4SF))); // vector of four single floats
  3.  
  4. typedef union
  5. {
  6.   v4sf v;
  7.   float f[4];
  8. } vector;
  9.  
  10. void inline normalise(vector *v)
  11. {
  12.         v4sf tmp;
  13.         tmp = __builtin_ia32_mulps(v->v, v->v);
  14.         tmp = __builtin_ia32_haddps(tmp, tmp);
  15.         tmp = __builtin_ia32_haddps(tmp, tmp);
  16.         tmp = __builtin_ia32_rsqrtss(tmp);
  17.         tmp = __builtin_ia32_shufps(tmp, tmp, 0x00);
  18.         v->v = __builtin_ia32_mulps(v->v, tmp);
  19. }
  20.  
  21. void inline normalise2(vector *v)
  22. {
  23.         float t = 1 / sqrtf(v->f[0] * v->f[0] + v->f[1] * v->f[1] + v->f[2] * v->f[2] + v->f[3] * v->f[3]);
  24.         v->f[0] *= t;
  25.         v->f[1] *= t;
  26.         v->f[2] *= t;
  27.         v->f[3] *= t;
  28. }
  29.  
  30. void foo()
  31. {
  32.   vector a, b;
  33.  
  34.   b.f[0] = a.f[0] = 40.0f;
  35.   b.f[1] = a.f[1] = 5.0f;
  36.   b.f[2] = a.f[2] = -50.0f;
  37.   b.f[3] = a.f[3] = 0.0f;
  38.  
  39.   printf("A:   %f %f %f %f n", a.f[0], a.f[1], a.f[2], a.f[3]);
  40.   printf("B:   %f %f %f %f n", b.f[0], b.f[1], b.f[2], b.f[3]);
  41.  
  42.   normalise(&a);
  43.   normalise2(&b);
  44.  
  45.   printf("SSE: %f %f %f %f n", a.f[0], a.f[1], a.f[2], a.f[3]);
  46.   printf("C:   %f %f %f %f n", b.f[0], b.f[1], b.f[2], b.f[3]);
  47.  
  48. }
  49.  
  50. int main()
  51. {
  52.   foo();
  53.   return 0;
  54. }

 
Chris

January 03, 2005, 05:20 PM

What do you expect ? You may even notice different results with optimization enabled or disabled. Microsoft's C++ compilers know three different precision enforcement levels when generating FPU code.
Also the internal precisions differ, the FPU uses 80 bit numerics, truncated to 32/64 bits on storage, and SSE uses 32 bits. Actually your SSE solution is worse, because SSE uses an approximation for the inverse of the square root, that's why you see the precision hit. You've got to live with it.

The correct solution (arbitrary precision, output rounded to 10 digits)

0.6227991553, 0.07784989443, 0.07784989443

The message is: Don't rely on floating point precision if you need to reproduce something, be machine independent, etc.

 
Crowley9

January 03, 2005, 07:19 PM

The reciprocal square root function is only an approximation (or rather, it is "more" approximate than 1.0/sqrt(x)):
http://www.tommesani.com/SSEReciprocal.html

Edit: Ah, I just see that was mentioned above.

 
elFarto

January 04, 2005, 05:31 AM

Yeah, That's what I discovered. Replacing the rrsqrtss with a sqrtss and a 1.0f / and it produced the correct result.

I should have expected my first attempt at assmebler wouldn't turn out too good :)

Thanks and Regards
elFarto

 
mssillyfingers

March 04, 2005, 03:05 PM

hiya
i know i shouldn't be doing this
but i am really missing you hun, i'm also really worried about you
i hope your'e o.k
if you want to reply just send me an email
loadsa luv
xxx

 
mssillyfingers

March 04, 2005, 03:08 PM

hiya
i know i shouldn't be doing this
but i am really missing you hun, i'm also really worried about you
i hope your'e o.k
if you want to reply just send me an email
loadsa luv
xxx

 
This thread contains 6 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.