- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在 GCC 5.3 中,以下代码使用 -O3 -fma
float mul_add(float a, float b, float c) {
return a*b + c;
}
生成以下程序集
vfmadd132ss %xmm1, %xmm2, %xmm0
ret
I noticed GCC doing this with -O3
already in GCC 4.8 .
带有 -O3 -mfma
的 Clang 3.7 产生
vmulss %xmm1, %xmm0, %xmm0
vaddss %xmm2, %xmm0, %xmm0
retq
但是使用 -Ofast -mfma
的 Clang 3.7 生成的代码与使用 -O3 fast
的 GCC 生成的代码相同。
我很惊讶 GCC 使用 -O3
因为来自 this answer它说
The compiler is not allowed to fuse a separated add and multiply unless you allow for a relaxed floating-point model.
This is because an FMA has only one rounding, while an ADD + MUL has two. So the compiler will violate strict IEEE floating-point behaviour by fusing.
但是,来自 this link它说
Regardless of the value of FLT_EVAL_METHOD, any floating-point expression may be contracted, that is, calculated as if all intermediate results have infinite range and precision.
所以现在我很困惑和担心。
-O3
结合使用是否合理?__STDC_IEC_559__
这不是自相矛盾吗?自 FMA can be emulated in software FMA似乎应该有两个编译器开关:一个告诉编译器在计算中使用FMA,一个告诉编译器硬件有FMA。
显然这可以通过选项 -ffp-contract
来控制。对于 GCC,默认值为 -ffp-contract=fast
而对于 Clang,则不是。 -ffp-contract=on
和 -ffp-contract=off
等其他选项不会产生 FMA 指令。
例如,带有 -O3 -mfma -ffp-contract=fast
的 Clang 3.7 生成 vfmadd132ss
。
我检查了一些 #pragma STDC FP_CONTRACT
设置为 ON
和 OFF
与 -ffp-contract
的排列设置为 on
、off
和 fast
。在所有情况下,我还使用了 -O3 -mfma
。
有了 GCC,答案就很简单了。 #pragma STDC FP_CONTRACT
ON 或 OFF 没有区别。只有 -ffp-contract
很重要。
GCC 它使用 fma
和
-ffp-contract=fast
(默认)。对于 Clang,它使用 fma
-ffp-contract=fast
。-ffp-contract=on
(默认)和 #pragma STDC FP_CONTRACT ON
(默认为 OFF
)。换句话说,对于 Clang,您可以使用 #pragma STDC FP_CONTRACT ON
获得 fma
(因为 -ffp-contract=on
是默认设置) 或使用 -ffp-contract=fast
。 -ffast-math
(因此 -Ofast
)设置 -ffp-contract=fast
。
我研究了 MSVC 和 ICC。
对于 MSVC,它使用带 /O2/arch:AVX2/fp:fast
的 fma 指令。对于 MSVC,/fp:precise
是默认值。
对于 ICC,它使用带 -O3 -march=core-avx2
的 fma(实际上 -O1
就足够了)。这是因为 ICC 默认使用 -fp-model fast
。但是 ICC 即使使用 -fp-model precise
也使用 fma。要使用 ICC 禁用 fma,请使用 -fp-model strict
或 -no-fma
。
因此默认情况下 GCC 和 ICC 在启用 fma 时使用 fma(GCC/Clang 使用 -mfma
或 ICC 使用 -march=core-avx2
)但 Clang 和MSVC 没有。
最佳答案
它不违反 IEEE-754,因为 IEEE-754 在这一点上遵从语言:
A language standard should also define, and require implementations to provide, attributes that allow and disallow value-changing optimizations, separately or collectively, for a block. These optimizations might include, but are not limited to:
...
― Synthesis of a fusedMultiplyAdd operation from a multiplication and an addition.
在标准 C 中,STDC FP_CONTRACT
pragma 提供了控制这种值更改优化的方法。因此,GCC 被许可在默认情况下执行融合,只要它允许您通过设置 STDC FP_CONTRACT OFF
来禁用优化。不支持意味着不遵守 C 标准。
关于c - 融合乘加和默认舍入模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34436233/
我在 ASP.NET MVC 中有一个发票页面。 我正在计算 GST。 在 javascript 中这是结果。 165.45 * 0.1 = 16.544999999999998 在 C# 中我得到
在 JavaScript 中,我想将其减少到小数点后 5 位。不过,我不能简单地四舍五入并得到 0.03085,我需要进一步查看数字并将所有数字向上舍入,以便得到 0.03086。 输入:0.0308
有人可以解释为什么 R 这样做吗?在整数值上舍入最大值和最小值似乎非常有缺陷。 summary(1:1283932) Min. 1st Qu. Median Mean 3rd Qu.
所以基本上我正在做一个物理实验,在我的表格中,我希望我的数据四舍五入到与误差相同的精度,四舍五入为 1 sig fig。 例如,如果我有以下内容: angle signif(c(1.111,2.22
考虑以下 C# 代码... double x = Math.Round(72.6d, 2, MidpointRounding.ToZero); double y = Math.Round(82.6d,
我正在学习 BigDecimal,我希望它检索我输入的确切数字,以下代码正在处理该数字,我不知道为什么 public static BigDecimal parseFromNumberString(S
double y1 = 0; double y2 = 0; double i = 0.025; double n = 2; double h1 = 2000; double h2 = 4000
所以在下面的一组代码中,出于某种原因我得到了完全错误的答案...... import java.util.*; import java.io.*; import java.lang.*; import
在 Python 中,我想将两个数字相除,如果答案不是整数,我希望将数字四舍五入为上面的数字。 例如 100/30 不是给 33.3 而是给 4。谁能建议如何做到这一点?谢谢。 最佳答案 您可以使用
我需要对一个 float 进行四舍五入。例如 4.00011 。内置函数 round() 总是在数字 > .5 时向上舍入,在 = 0 val *= 10 ** precision r
我的代码: // Convert SATOSHIS to BITCOIN static double SATOSHI2BTC(const uint64_t& value) {
我想让我的 tableView 看起来像这样: 我有问题。只有在我点击单元格后,我的右角才会变圆。当 View 出现时,它看起来像这样: 点击后像这样: 这是我的代码: extension UITab
这个问题在这里已经有了答案: Precision String Format Specifier In Swift (31 个答案) 关闭 8 年前。 除了覆盖当前转换为字符串的方法之外,是否有一种
>>> a = 0.3135 >>> print("%.3f" % a) 0.314 >>> a = 0.3125 >>> print("%.3f" % a) 0.312 >>> 我期待 0.313
我有自动将输入字段加在一起的 javascript 函数,但是添加像 1.35 + 1.35 + 1.35 这样的数字会得到 4.050000000000001 的输出,这只是一个例子。如何将总数四舍
这可能是 x86 FPU 专家的问题: 我正在尝试编写一个生成范围 [min,max] 内的随机浮点值的函数。问题是我的生成器算法(浮点 Mersenne Twister,如果你好奇的话)只返回 [1
我一定错过了一些明显的东西。 select CEILING(85/30) = 2 85/30 = 2.83333 我希望该值为 3。 CEILING 函数不应该为我取整吗? 最佳答案 尝试 SELEC
我有一个关于 eclipse rcp 中的 ctabfolders 的问题。我创建了一个 e4 RCP 应用程序,其中包含一个包含堆栈部分容器的窗口,其中包含一个堆栈。该堆栈包含 1 个部分。在这一部
Closed. This question needs details or clarity。它当前不接受答案。
我读过其他一些帖子,它们似乎对其他人有用,但当我尝试它们时,它们不起作用。我刚刚开始学习Java编程,我似乎不明白如何四舍五入。 我试过了 answer = input * input; answer
我是一名优秀的程序员,十分优秀!