From: Klaus N. <kl...@ma...> - 2001-03-26 12:37:23
|
Hi, I have been thinking about making a faster 'log_2' function by programming it myself instead of using the one in libc. I started by looking at the gl_sqrt function that is being used in the Mesa-library in the file 'src/mmath.c'. I made a small program to test both the speed and the precision and at home on a K6-2 with Debian-2.1 I had a rather terrible result: If I did not use the compiler-option '-fstrict-aliasing' the libc-sqrt is almost double as fast as the 'gl_sqrt', while the precision is o.k. 1% error or so. But with '-fstrict-aliasing', which was used in my auto-generated Makefile for Mesa, the results for sqrt are for some numbers up to 10 times greater than the once generated by gl_sqrt, while the speed for normal sqrt is still higher. So I wanted to write you and tell this but then I just tried my program here on a PIII whith RH7.0 I got complete different results: gl_sqrt is a bit faster than sqrt, and 'strict-aliasing' has no effect on speed or results. The error in the results is always up to 20%. If I use '-mcpu=pentium-pro -march=pentium-pro' the precision is completely wrong (20 or 30 digit number instead of 1.000). Maybe you want to try yourself and find out if I did something wrong or what could be happening. To compile put the program below into Mesa/src and I compiled at home with gcc -I../include -ffast-math -fexpensive-optimizations -fstrict-aliasing -mcpu=k6 -march=k6 -DUSE_X86_ASM -DFAST_MATH -O3 test.c mmath.c -o test The program is: #include "mmath.h" #include <time.h> #define NEW_SQRT(X) gl_sqrt(X) #define OLD_SQRT(X) ((float)sqrt(X)) int main() { float x,y; clock_t start, end; _mesa_init_math(); x = 0.0f; y = 0.0f; start = clock(); while (x<1000000.0f) { y *= NEW_SQRT(x); x += 0.1f; } end = clock(); printf ("Time for mesa sqrt: %f\n", (float)(end-start)/CLOCKS_PER_SEC); x = 0.0f; y = 0.0f; start = clock (); while (x<1000000.0f) { y *= OLD_SQRT(x); x += 0.1f; } end = clock(); printf ("Time for normal sqrt: %f\n", (float)(end-start)/CLOCKS_PER_SEC); x= 1.0f; while (x<100.0f) { printf("x = %f\tMesa_square(x)/standard_square(x) = %f\n", x, OLD_SQRT(x)/NEW_SQ RT(x)); x+=2.4; } } |