为什么一定要-ffast-math
配合g++使用s来实现循环的向量化double
?我不喜欢-ffast-math
,因为我不想失去精度。
4 回答
你不一定会失去精度-ffast-math
。它仅影响 等的处理NaN
以及Inf
执行操作的顺序。
如果您有一段特定的代码不希望 GCC 重新排序或简化计算,您可以使用asm
语句将变量标记为正在使用。
例如,以下代码对f
. 但是,这两个f += g
和f -= g
操作可能会被 gcc 优化掉:
static double moo(double f, double g)
{
g *= 4503599627370496.0; // 2 ** 52
f += g;
f -= g;
return f;
}
在 x86_64 上,您可以使用此asm
语句来指示 GCC 不要执行该优化:
static double moo(double f, double g)
{
g *= 4503599627370496.0; // 2 ** 52
f += g;
__asm__("" : "+x" (f));
f -= g;
return f;
}
不幸的是,您将需要为每种架构进行调整。在 PowerPC 上,+f
使用+x
.
很可能是因为矢量化意味着您可能有不同的结果,或者可能意味着您错过了浮点信号/异常。
如果您正在为 32 位 x86 编译,则 gcc 和 g++ 默认使用 x87 进行浮点数学运算,在 64 位上它们默认使用 SSE,但是 x87 可以并且将为相同的计算产生不同的值,因此 g++ 不太可能如果它不能保证您将获得相同的结果,除非您使用-ffast-math
或它打开的某些标志,否则将考虑矢量化。
基本上它归结为矢量化代码的浮点环境可能与非矢量化代码的浮点环境不同,有时在某些方面很重要,如果差异对你来说并不重要,比如
-fno-math-errno -fno-trapping-math -fno-signaling-nans -fno-rounding-math
但首先查看这些选项并确保它们不会影响程序的正确性。-ffinite-math-only
也可能有帮助
To enable auto-vectorization with gcc, ffast-math is not actually necessary. See https://gcc.gnu.org/projects/tree-ssa/vectorization.html#using
To enable vectorization of floating point reductions use -ffast-math or -fassociative-math.
Using -fassociative-math should be sufficient.
This has been the case since 2007, see https://gcc.gnu.org/projects/tree-ssa/vectorization.html#oldnews
- -fassociative-math can be used instead of -ffast-math to enable vectorization of reductions of floats (2007-09-04).