Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fast atan2




On Jan 20, 2005, at 12:39 PM, Ian Ollmann wrote:



On Jan 20, 2005, at 12:26 PM, Ian Ollmann wrote:


best libm time for 1000 calls: 3.06011e-06 seconds (792544)

Hmm... that time suggests 6 cycles for a atan, which I think is not reasonable. I probably got defeated by a compiler optimization here somewhere...

Alrighty, once the compiler is defeated, we see that the speed improvement is there:


ollmia:/tmp iano$ gcc -O3 main4.c -Wmost
ollmia:/tmp iano$ ./a.out
best libm   time for 1000 calls: 0.000113 seconds (801939)
best cheesy time for 1000 calls: 0.000017 seconds (800454)

atan2(0.755605, 0.45865): 1.02525 0.977473 0.0477748
atan2(0.532767, 0.218959): 1.18086 1.11326 0.0675938
atan2(0.991037, 0.365339): 1.21761 1.1477 0.0699071
atan2(0.266145, 0.0907329): 1.24224 1.17144 0.0708017
atan2(0.499741, 0.147533): 1.28373 1.21277 0.0709664
atan2(0.651646, 0.215248): 1.25176 1.18077 0.0709946
atan2(0.526338, 0.160083): 1.27554 1.20446 0.0710766
atan2(0.861622, 0.277198): 1.25954 1.18845 0.0710852
atan2(0.376933, 0.120691): 1.26092 1.18983 0.071095
atan2(0.660927, 0.203913): 1.27154 1.20043 0.0711042
ollmia:/tmp iano$ cat main4.c
#include <math.h>
#include <stdint.h>
#include <mach/mach_time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static double MySubtractTime( uint64_t endTime, uint64_t startTime )
{
    uint64_t    difference = endTime - startTime;
    static double conversion = 0.0;

    if( 0.0 == conversion )
    {
        mach_timebase_info_data_t       timebase;
        kern_return_t                   err;

        memset( &timebase, 0, sizeof( timebase ));

        err = mach_timebase_info( &timebase );
        if( 0 != err )
            return err;

conversion = 1e-9 * (double) timebase.numer / (double) timebase.denom;
}


    return (double) difference * conversion;
}

float arctan2(float y, float x)
{
   float  angle;
   float coeff_1 = M_PI/4;
   float coeff_2 = 3*coeff_1;
   float abs_y = fabsf(y)+1e-10;      // kludge to prevent 0/0 condition
   if (x>=0)
   {
      double r = (x - abs_y) / (x + abs_y);
      angle = coeff_1 - coeff_1 * r;
   }
   else
   {
      float r = (x + abs_y) / (abs_y - x);
      angle = coeff_2 - coeff_1 * r;
   }

   if (y < 0)
           return(-angle);     // negate if in quad III or IV
   else
           return(angle);
}

float x[1000], y[1000];

int main( void )
{
        uint64_t        startTime, endTime;
        double          currentTime, bestTime;
        int i, j;
        float sum = 0.0;
        double maxError = 0;

        for( i = 0; i < 1000; i++ )
        {
                x[i] = (double) rand() / (double) RAND_MAX;
                y[i] = (double) rand() / (double) RAND_MAX;
        }



bestTime = 1e20;
for( i = 0; i < 1000; i++ )
{
startTime = mach_absolute_time();
for( j = 0; j < 1000; j++ )
sum += atan2f(x[j], y[j] );
endTime = mach_absolute_time();
currentTime = MySubtractTime( endTime, startTime );
if( currentTime < bestTime )
bestTime = currentTime;
}
printf("best libm time for 1000 calls: %f seconds (%g)\n", bestTime, sum );


bestTime = 1e20;
sum = 0;
for( i = 0; i < 1000; i++ )
{
startTime = mach_absolute_time();
for( j = 0; j < 1000; j++ )
sum += arctan2(x[j], y[j] );
endTime = mach_absolute_time();
currentTime = MySubtractTime( endTime, startTime );
if( currentTime < bestTime )
bestTime = currentTime;
}
printf("best cheesy time for 1000 calls: %f seconds (%g)\n", bestTime, sum );


//some cheesy error checking to go with the cheesy function
//please note that this is VERY cheesy and should in no way to be construed
//to be even hinting at an endorsement of anything.
for( j = 0; j < 1000; j++ )
{
float test = arctan2(x[j], y[j] );
float correct = atan2f( x[j], y[j] );
double currentError = correct - test;
if( currentError > maxError )
{
printf( "atan2(%g, %g): %g %g %g\n", x[j], y[j], correct, test, currentError );
maxError = currentError;
}


        }

        return 0;
}

_______________________________________________
Do not post admin requests to the list. They will be ignored.
PerfOptimization-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/perfoptimization-dev/email@hidden

This email sent to email@hidden
References: 
 >Fast atan2 (From: Robert Purves <email@hidden>)
 >Re: Fast atan2 (From: rick <email@hidden>)
 >Re: Fast atan2 (From: Ian Ollmann <email@hidden>)
 >Re: Fast atan2 (From: Ian Ollmann <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.