Search code examples
c++performancec++11profilingabsolute-value

Speeding up double absolute value in C++


I'm profiling my code and optimized everything I could, coming down to a function which looks something like this:

double func(double a, double b, double c, double d, int i){
    if(i > 10 && a > b || i < 11 && a < b)
        return abs(a-b)/c;
    else
        return d/c;
}

It is called millions of times during the run of the program and profiler shows me that ~80% of all time is spent on calling abs().

  1. I replaced abs() with fabs() and it gave about 10% speed up which doesn't make much sense to me as I heard multiple times that they are identical for floating point numbers and abs() should be used always. Is it untrue or I'm missing something?

  2. What would be the quickest way to evaluate absolute value for a double which could further improve the performance?

If that matters, I use g++ on linux X86_64.


Solution

  • Do all 3 computations. Stick the result in a 3 element array. Use non branching arithmetic to find the correct array index. Return that result.

    Ie,

    bool icheck = i > 10;
    bool zero = icheck & (a > b);
    bool one = !icheck & (b > a);
    bool two = !zero & !one;
    int idx = one | (two << 1);
    return val[idx];
    

    Where val holds the result of the three computations. The use of & instead of && is important.

    This removes your branch prediction problems. Finally, make sure the looping code can see the implementation, so the call overhead can be eliminated.