Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is different about C++ math.h abs() compared to my abs()

I am currently writing some glsl like vector math classes in C++, and I just implemented an abs() function like this:

template<class T>
static inline T abs(T _a)
{
    return _a < 0 ? -_a : _a;
}

I compared its speed to the default C++ abs from math.h like this:

clock_t begin = clock();
for(int i=0; i<10000000; ++i)
{
    float a = abs(-1.25);
};

clock_t end = clock();
unsigned long time1 = (unsigned long)((float)(end-begin) / ((float)CLOCKS_PER_SEC/1000.0));

begin = clock();
for(int i=0; i<10000000; ++i)
{
    float a  = myMath::abs(-1.25);
};
end = clock();
unsigned long time2 = (unsigned long)((float)(end-begin) / ((float)CLOCKS_PER_SEC/1000.0));

std::cout<<time1<<std::endl;
std::cout<<time2<<std::endl;

Now the default abs takes about 25ms while mine takes 60. I guess there is some low level optimisation going on. Does anybody know how math.h abs works internally? The performance difference is nothing dramatic, but I am just curious!

like image 907
moka Avatar asked May 20 '10 21:05

moka


People also ask

What is the difference between abs () and fabs () functions in C?

Both will return the absolute value of a number. The difference is that math. fabs(number) will always return a floating-point number even if the argument is an integer, whereas abs() will return a floating-point or an integer depending upon the argument.

Is abs function in math H?

h library contains predefined function abs() for computing the absolute value of integers. By absolute value, it means the function returns the positive value of an integer.

What does abs () do in C?

The C library function int abs(int x) returns the absolute value of int x.

What is the meaning of abs () in C++?

The abs() function in C++ returns the absolute value of an integer number. This function is defined in the cstdlib header file.


1 Answers

Since they are the implementation, they are free to make as many assumptions as they want. They know the format of the double and can play tricks with that instead.

Likely (as in almost not even a question), your double is the binary64 format. This means the sign has it's own bit, and an absolute value is merely clearing that bit. For example, as a specialization, a compiler implementer may do the following:

template <>
double abs<double>(const double x)
{
    // breaks strict aliasing, but compiler writer knows this behavior for the platform
    uint64_t i = reinterpret_cast<const std::uint64_t&>(x);
    i &= 0x7FFFFFFFFFFFFFFFULL; // clear sign bit

    return reinterpret_cast<const double&>(i);
}

This removes branching and may run faster.

like image 172
GManNickG Avatar answered Sep 17 '22 02:09

GManNickG