Search code examples
gccg++doublevectorizationfast-math

Auto vectorization on double and ffast-math


Why is it mandatory to use -ffast-math with g++ to achieve the vectorization of loops using doubles? I don't like -ffast-math because I don't want to lose precision.


Solution

  • You don’t necessarily lose precision with -ffast-math. It only affects the handling of NaN, Inf etc. and the order in which operations are performed.

    If you have a specific piece of code where you do not want GCC to reorder or simplify computations, you can mark variables as being used using an asm statement.

    For instance, the following code performs a rounding operation on f. However, the two f += g and f -= g operations are likely to get optimised away by gcc:

    static double moo(double f, double g)                                      
    {                                                                          
        g *= 4503599627370496.0; // 2 ** 52                                    
        f += g;                                                                
        f -= g;                                                                
        return f;                                                            
    }                                                                     
    

    On x86_64, you can use this asm statement to instruct GCC not to perform that optimisation:

    static double moo(double f, double g)                                      
    {                                                                          
        g *= 4503599627370496.0; // 2 ** 52                                    
        f += g;                                                                
        __asm__("" : "+x" (f));
        f -= g;
        return f;
    }
    

    You will need to adapt this for each architecture, unfortunately. On PowerPC, use +f instead of +x.