问题标签 [fast-math]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
379 浏览

c - 来自 -ffast-math 的 gcc 链接器行为的奇怪结果

我注意到编译器链接器的标志以我无法理解的方式影响正在运行的代码的一个有趣现象。

我有一个库,它提供相同算法的不同实现,以测试这些不同实现的运行速度。

最初,我用一对相同的实现测试了这种情况,以检查是否发生了正确的事情(两者的运行速度大致相同)。我首先使用以下编译器标志编译对象(每个实现一个):

然后在链接期间通过 gcc 以下标志:

这提供了一个运行速度极快的库,但奇怪的是,对于链接期间包含在参数中的第一个对象,它可靠且可重复地快了约 7%(因此,如果先链接,则任一实现都更快)。

所以:

对比

第一种情况是 obj1 中的实现比 obj2 中的实现运行得更快。在第二种情况下,情况正好相反。需要明确的是,除了函数条目名称外,两种情况下的代码都是相同的。

-Ofast现在我通过在链接期间删除标志来删除这个奇怪的链接参数顺序差异(实际上加快了一点) 。

-Ofast我可以通过更改为来复制几乎相同的情况-O3 -ffast-math,但在这种情况下,我需要-ffast-math在链接期间提供,这再次导致奇怪的订购速度差异。我不确定为什么在链接期间保持加速-Ofast而不是-ffast-math-ffast-math没有传递时保持加速,但我可以接受这可能是由于链接时间优化在一种情况下传递相关信息而不是在另一种情况下传递。但这并不能解释速度差异。

删除-ffast-math意味着它的运行速度慢了约 8 倍。

是否有人能够阐明可能导致这种影响的原因?我真的很想知道是什么导致了这种有趣的行为,所以我不能不小心触发它。

运行速度测试是在 python 中使用库和 timeit 的包装器执行的,我相当确定这是在做正确的事情(我可以​​旋转订单和显示 python 副作用的东西可以忽略不计)。

我还测试了库的输出正确性,所以我也可以相当有信心。

0 投票
1 回答
2550 浏览

gcc - 什么是 ICC/Clang 中的 -fp-model fast=1 等价物

正如我在英特尔网站上看到的:

Intel 编译器使用 /fp-model fast=1 作为默认值。这种优化有利于速度而不是标准合规性。您可以使用编译器选项 -mieee-fp 来获得兼容的代码。

我对 ICC 中的fp-model选项的理解是(如果我错了,请纠正我):

  • precise对应于 GCC 和 Clang 中的默认设置,
  • fast=2类似于-ffast-math,
  • fast=1介于两者之间。

GCC 或 Clang 中的哪些选项会使浮点数学与 Intel 的默认值最相似-fp-model fast=1

0 投票
1 回答
246 浏览

c - 使用 -ffast-math 编译时 AVX 代码段错误?

我正在尝试使用 GCC 内置 simd 支持编写几个内核。我有这段代码对 AVX 点积内核进行基准测试:

奇怪的是,当编译时:

第一次访问 avx_dot 中的 temp 时出现段错误。但是,当编译时:

IE,没有 -ffast-math ,它运行良好。我很困惑,因为我相信快速数学不应该影响内存访问,所以我不知道段错误来自哪里。

我正在运行:

任何人都可以在他们的机器上确认这种行为并阐明正在发生的事情吗?

0 投票
0 回答
134 浏览

gcc - gcc -Ofast 是否启用矢量化?

我目前正在使用以下 2 个标志设置编译 spec2000 艺术基准:

  1. -Ofast -m32 -march=native
  2. -Ofast -m32 -march=native -fno-tree-vectorize

第二个设置只是禁用矢量化器。但是,当我检查 2 个设置的 objdump 时,它们都显示了一些打包指令,例如vmovapd,vxorpd等。

谁能提供一些解释?谢谢。

0 投票
2 回答
2691 浏览

gcc - Can I make my compiler use fast-math on a per-function basis?

Suppose I have

and I want to compile one instantiation with -ffast-math (--use-fast-math for nvcc), and the other instantiation without it.

This can be achieved by instantiating each of the variants in a separate translation unit, and compiling each of them with a different command-line - with and without the switch.

My question is whether it's possible to indicate to popular compilers (*) to apply or not apply -ffast-math for individual functions - so that I'll be able to have my instantiations in the same translation unit.

Notes:

  • If the answer is "no", bonus points for explaining why not.
  • This is not the same questions as this one, which is about turning fast-math on and off at runtime. I'm much more modest...

(*) by popular compilers I mean any of: gcc, clang, msvc icc, nvcc (for GPU kernel code) about which you have that information.

0 投票
1 回答
1098 浏览

c++ - 为什么 std::inner_product 比天真的实现慢?

这是我对点积的天真实现:

这是使用 C++ 库:

我跑了一些基准(代码在这里https://github.com/ijklr/sse),库版本要慢很多。我的编译器标志是-Ofast -march=native

0 投票
1 回答
1760 浏览

c++ - 严格的别名,-ffast-math 和 SSE

考虑以下程序:

如果我用 Apple Clang 7.0.2 编译和不编译-ffast-math,我会得到预期的输出0 0 0 0

然而,在更新到 8.1.0 之后(对不起,我不知道这对应于哪个 Clang 的实际版本 - Apple 不再发布该信息),-ffast-math似乎打破了这一点:

我怀疑这是因为严格的别名规则或类似的东西。谁能解释这种行为?

编辑:我忘了提到,如果你这样做nans = { std::nanf(nullptr), ...,效果很好。

还查看Godbolt,似乎 Clang 3.8.1 和 Clang 3.9 之间的行为发生了变化——后者删除了cmpordps指令。GCC 7.1 似乎保留了它。

0 投票
1 回答
352 浏览

x86 - 像 Denormals-Are-Zero (DAZ) 这样的非正规标志会影响相等比较吗?

如果我有 2 个具有不同位模式的非正规浮点数并比较它们是否相等,结果是否会受到常用处理器上的非正规化零标志、刷新为零标志或其他标志的影响?

还是这些标志只影响计算而不影响相等检查?

0 投票
1 回答
222 浏览

gcc - GCC 的 ffast-math 是否具有跨平台或编译器版本的一致性保证?

我想编写跨平台的 C/C++,它在不同的环境中具有可重现的行为。

我知道 gcc 的 ffast-math 可以实现各种浮点近似。这很好,但我需要两个单独编译的二进制文件来产生相同的结果。

假设我总是使用 gcc,但对于 Windows、Linux 或其他任何东西以及不同的编译器版本都是不同的。

是否可以保证这些编译将为相同的源代码产生相同的浮点近似集?

0 投票
0 回答
146 浏览

c - 生成“确定性”浮点运算的标志。指针与“快速数学”对齐?

gcc 中的-ffast-math选项允许编译器重新排序浮点运算以更快地执行。

这可能会导致这些操作的结果之间存在细微差异,具体取决于指针的对齐方式。例如,在 x64 上,一些优化指令 (AVX) 在 128 位对齐的指针上更快,因此允许编译器这样做是有道理的。

这是一个简单程序的示例,它显示了现代 CPU 上的这种行为:

编译时可能会输出-Ofast

问题

是否有一个神奇的标志礼貌地要求编译器不要生成对指针对齐敏感的代码而不完全禁止“快速数学”优化?

更多细节

这是我的 gcc 的配置:

我只是用“gcc -Ofast”编译了上面的代码。

通过查看生成的汇编代码,编译器似乎正在实现以下伪代码:

例如,如果 a 是数组 {0, 1, 2,.., 10},则sum计算:

  • ((0+2+4+6+8)+(1+3+5+7+9))+10 如果它是“对齐的”

  • ((2+4+6+8+10)+(1+3+5+7+9))+1 如果 a 没有“对齐”

这是汇编代码(评论是我的,可能是错误的):