gpt4 book ai didi

c++ - 将融合乘法累加用于 double 有多有利?

转载 作者:行者123 更新时间:2023-12-01 14:25:16 24 4
gpt4 key购买 nike

我试图通过查看生成的汇编代码来了解使用带有双参数的 std::fma 是否有利,我正在使用标志“-O3”,并且我正在比较这两个例程的程序集:

#include <cmath>
#define FP_FAST_FMAF

float test_1(const double &a, const double &b, const double &c ){
return a*b + c;
}
float test_2(const double &a, const double &b, const double &c ){
return std::fma(a,b,c);
}

使用 Compiler Explorer工具,这是为两个例程生成的程序集:

test_1(double const&, double const&, double const&):
movsd xmm0, QWORD PTR [rdi] #5.12
mulsd xmm0, QWORD PTR [rsi] #5.14
addsd xmm0, QWORD PTR [rdx] #5.18
cvtsd2ss xmm0, xmm0 #5.18
ret #5.18
test_2(double const&, double const&, double const&):
push rsi #7.65
movsd xmm0, QWORD PTR [rdi] #8.12
movsd xmm1, QWORD PTR [rsi] #8.12
movsd xmm2, QWORD PTR [rdx] #8.12
call fma #8.12
cvtsd2ss xmm0, xmm0 #8.12
pop rcx #8.12
ret

并且程序集不会因使用可用于 icc 或 gcc 的最新版本而改变。关于这两个例程的性能让我感到困惑的是,虽然对于 test_1 只有一个内存操作(movsd),但对于 test_2 有三个,并且考虑到内存操作的延迟介于比浮点运算的延迟大一到两个数量级,test_1 的性能应该更高。因此,在哪些情况下建议使用 std::fma?我的假设有什么错误?

最佳答案

如果您的问题仅与内存操作的数量有关,请务必注意 mulsdaddsd 在您的示例中也是内存操作。内存操作由寄存器名称周围的方括号指示,而不是汇编助记符本身。

如果您仍然好奇使用 std::fma 是否有利,答案可能是“视情况而定”。

当您通过查看汇编来分析性能时,向编译器提供至少一些关于您的目标体系结构的信息几乎是必不可少的。 std::fma 使用硬件 FMA 指令(如果它们在目标架构上可用),因此 std::fma 是否总体上提高了性能并不是一个真正可以回答的问题。

如果你specify -mfma in Compiler Explorer ,编译器有一些信息可以用来生成更高效的代码。您还可以指定 -march=[your architecture] 如果支持,它将自动为您设置 -mfma


此外,还有一大堆关于 std::fma(a*b)+c 结果的细微差异的蠕虫病毒四舍五入是用 float 处理的。 std::fma 在两次浮点运算中只循环一次,而 (a*b)+c 可能[1] a*b,将结果以64位存储,将此值加上c,然后将结果以64位存储。

如果你想在你的计算中最小化浮点运算错误,std::fma 可能是更好的选择,因为它保证你只会将宝贵的位从你宝贵的 float 中剥离一次.


[1] 是否进行这种额外舍入取决于您的编译器、优化设置和架构设置: Compiler Explorer msvc、gcc、icc、clang 的示例

关于c++ - 将融合乘法累加用于 double 有多有利?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62273226/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com