Different compilers question


(IlDuca86) #1

I’m looking inside ET math code, and i found a definition i would like to know more about. In q_shared.h you can find this code :

//======================= MAC OS X SERVER DEFINES =====================

#if defined(MACOS_X)

#define MAC_STATIC

#define CPUSTRING	"MacOS_X"

#define	PATH_SEP	'/'

// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction, 
// runs *much* faster than calling sqrt(). We'll use two Newton-Raphson 
// refinement steps to get bunch more precision in the 1/sqrt() value for very little cost. 
// We'll then multiply 1/sqrt times the original value to get the sqrt. 
// This is about 12.4 times faster than sqrt() and according to my testing (not exhaustive) 
// it returns fairly accurate results (error below 1.0e-5 up to 100000.0 in 0.1 increments). 

static inline float idSqrt(float x) {
    const float half = 0.5;
    const float one = 1.0;
    float B, y0, y1;

    // This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0
    if (Q_fabs(x) == 0.0)
        return x;
    B = x;
    
#ifdef __GNUC__
    asm("frsqrte %0,%1" : "=f" (y0) : "f" (B));
#else
    y0 = __frsqrte(B);
#endif
    /* First refinement step */
    
    y1 = y0 + half*y0*(one - B*y0*y0);
    
    /* Second refinement step -- copy the output of the last step to the input of this step */
    
    y0 = y1;
    y1 = y0 + half*y0*(one - B*y0*y0);
    
    /* Get sqrt(x) from x * 1/sqrt(x) */
    return x * y1;
}
#define sqrt idSqrt


#endif

Ok i try to explain what i know, and please if i write some stupid ( aka wrong :stuck_out_tongue: ) things, please correct me.

Reading the programmer note, this function is able to calculate the square root of the “float x” input. I found out that GNUC is a macro alweys defined in the compiler GCC, that represent the GCC version. This means if we are using GCC to compile the source, we will use the code :

asm("frsqrte %0,%1" : "=f" (y0) : "f" (B));

GCC has an inline assembly compiler, and that’s called with the function asm(…), so this just add assembly routine “frsqrte” in the C code to calculate the reciprocal square root in a faster way.

If the macro GNUC is not defined, the code added is :

y0 = __frsqrte(B);

and i found in the net this is a PowerPC definition that calls the same function above ( in other words, do the same things, but that’s smaller to write :slight_smile: ), and it’s alweys defined in the Metrowerks MAC compiler.

This previous code is needed to have a first approximation of the reciprocal square root, used inside 2 Newton-Raphson steps to have a better precision ( like note says :slight_smile: ). Since that calculate the reciprocal square root, the function multiply it at the end with the input value to obtain the square root.

At last, there is a definition :

#define sqrt idSqrt

this means every time we will read “sqrt” function in the code, the used function will be “idSqrt”.

What i would like to know ( if i said right things ) is, when this code is added ? I means, i found nothing on the macro “MACOS_X” that, if def, will use this code… someone know more? Is MAC only definition? Because if this is false, why programmer decided to use this function ( that looks so good ) only for MAC, and not for other S.O. ( LINUX for exemple, with GCC )?

If i compile with Window( in exemple ), i will have a code that run 12.4 times slower that this, because i’ve not this definition but i use the standard sqrt, or the sqrt the note was talking about is the MAC one only ?

I’m making some test over few sqrt alghoritms, to know the fastest one :slight_smile:


(kamikazee) #2

Here, the assembly statement can be used because a PowerPC processor has an instruction to calculate the square root of a given number. Windows, which runs on an x86 platform, cannot use this because the Intel or AMD processors probably don’t have such an instruction.


(Rudi) #3

Which also most probably means that it’s not available on the new Macs. Meaning Universal (2.60d?) SDK version will have changed that statement.


(IlDuca86) #4

Here, the assembly statement can be used because a PowerPC processor has an instruction to calculate the square root of a given number. Windows, which runs on an x86 platform, cannot use this because the Intel or AMD processors probably don’t have such an instruction.

Really thanks for the answer, was what i thought too. I found Power Architecture is supported by lot of O.S. ( lot Linux O.S. , MAC , Windows NT , Playstation3 and Xbox360, etc ), but that’s only ( most ) provided by IBM processors.

Means AMD and Intel ( so most used, at last by me ) will not care about this feature.

That’s a pity :slight_smile: will give a look at other sqrt functions.