Why is it mandatory to use -ffast-math
with g++ to achieve the vectorization of loops using double
s? I don't like -ffast-math
because I don't want to lose precision.
相关问题
- Extract matrix elements using a vector of column i
- Do the Java Integer and Double objects have unnece
- Implicitly defined constructor deleted due to vari
- Error building gcc 4.8.3 from source: libstdc++.so
- Repeat but in variable sized chunks in numpy
相关文章
- 关于C#中 float、double、decimal 的运算不精确的问题。
- gcc/g++ gives me error “CreateProcess: No such fil
- Calls that precede a function's definition can
- How can I use gcc's -I command to add recursiv
- How do I know if std::map insert succeeded or fail
- How can I convert a OLE Automation Date value to a
- How to specify gcc flags (CXXFLAGS) particularly f
- Macro or function to construct a float (double) fr
Very likely because vectorization means that you may have different results, or may mean that you miss floating point signals/exceptions.
If you're compiling for 32 bit x86 then gcc and g++ default to using the x87 for floating point math, on 64 bit they default to sse, however the x87 can and will produce different values for the same computation so it's unlikely g++ will consider vectorizing if it can't guarantee that you will get the same results unless you use -ffast-math or some of the flags it turns on.
Basically it comes down to the floating point environment for vectorized code may not be the same as the one for non vectorized code, sometimes in ways that are important, if the differences don't matter to you, something like
but first look up those options and make sure that they won't affect your program's correctness.
-ffinite-math-only
may help alsoYou don’t necessarily lose precision with
-ffast-math
. It only affects the handling ofNaN
,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 twof += g
andf -= g
operations are likely to get optimised away by gcc:On x86_64, you can use this
asm
statement to instruct GCC not to perform that optimisation:You will need to adapt this for each architecture, unfortunately. On PowerPC, use
+f
instead of+x
.Because
-ffast-math
enables operands reordering which allows many code to be vectorized.For example to calculate this
the compiler is required to do the additions sequentially without
-ffast-math
, because floating-point math is neither commutative nor associative.That's the same reason why compilers can't optimize
a*a*a*a*a*a
to(a*a*a)*(a*a*a)
without-ffast-math
That means no vectorization available unless you have very efficient horizontal vector adds.
However if
-ffast-math
is enabled, the expression can be calculated like this (Look atA7. Auto-Vectorization
)Now the compiler can vectorize it easily by adding each column in parallel and then do a horizontal add at the end
It may be enabled by the
-fassociative-math
flag in gccFurther readings