与天真计算相比,FMA性能
FMA performance compared to naive calculation
我试图将浮点计算中的FMA性能(math.h
中的fma()
)与朴素的乘法和加法进行比较。测试很简单。我将对大的迭代次数重复相同的计算。为了进行精确的检查,我必须做到两件事。
- 计数时间中不应包含其他计算
- 单纯的乘法和加法不应优化为FMA
- 不应优化迭代。即迭代应该按照我的意图进行
为了实现上述目标,我做了以下事情:
- 函数是内联的,并且只包括所需的计算
- 使用g++
-O0
选项不优化乘法。(但当我查看转储文件时,它似乎为两者生成了几乎相同的代码) - 使用
volatile
但结果显示,与简单的乘法和加法相比,fma()
几乎没有差异,甚至更慢这是我想要的结果吗(即,它们在速度方面并没有真正的不同)还是我做错了什么
规格
- Ubuntu 14.04.2
- G++4.8.2
- Intel(R)Core(TM)i7-4770(3.4GHz,8MB L3缓存)
我的代码
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <chrono>
using namespace std;
using namespace chrono;
inline double rand_gen() {
return static_cast<double>(rand()) / RAND_MAX;
}
volatile double a, b, c;
inline void pure_fma_func() {
fma(a, b, c);
}
inline void non_fma_func() {
a * b + c;
}
int main() {
int n = 100000000;
a = rand_gen();
b = rand_gen();
c = rand_gen();
auto t1 = system_clock::now();
for (int i = 0; i < n; i++) {
non_fma_func();
}
auto t2 = system_clock::now();
for (int i = 0; i < n; i++) {
pure_fma_func();
}
auto t3 = system_clock::now();
cout << "non fma" << endl;
cout << duration_cast<microseconds>(t2 - t1).count() / 1000.0 << "ms" << endl;
cout << "fma" << endl;
cout << duration_cast<microseconds>(t3 - t2).count() / 1000.0 << "ms" << endl;
}
是的,你做的事情完全错了。至少两个多岁的年轻人。但让我们保持简单。
Used g++ -O0 option not to optimize the multiplication
这使得您的整个结果完全无关。有趣的事实是:在任何一种情况下,函数调用的成本都可能大于计算的成本。
从根本上讲,没有启用优化的基准测试结果是完全没有意义的。你不能只是关掉它们,抱着最好的希望。它们绝对必须启用。
其次,FMA与常规的乘法和加法是一个复杂的情况——在延迟与吞吐量以及其他问题上,乘法和加法可能是赢家。
简而言之,你的基准测试根本不是一个基准测试,它只是一堆随机指令,产生了毫无意义的垃圾。
如果你想要一个准确的基准,你必须准确地再现实际的使用情况——完全。包括周围的代码,编译器的优化,整个shebang。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- OpenMP阵列性能较差
- 递归列出所有目录中的C++与Python与Ruby的性能
- 大小相等但成员数量不同的结构之间的性能差异
- 为什么constexpr的性能比正常表达式差
- 在类中使用随机生成器时出现性能问题
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 海湾合作委员会 ARM 性能下降
- GCC 和 Clang 代码性能的巨大差异
- 在容量内调整矢量大小时的性能影响
- 了解算法的性能差异(如果以不同的编程语言实现)
- 未达到的情况会影响开关外壳性能
- QStringList vs list<shared_ptr<QString>> 性能比较C++
- 是否总是可以将使用递归编写的程序重写为不使用递归的程序C++,性能观点是什么?
- 哪种方法更好,性能明智
- C++ 特征库:引用的性能开销<>
- 与多个 for 循环与单个 for 循环 wrt 相关的性能从多映射获取数据
- 基于范围的 for 循环range_declaration中各种说明符之间的性能差异
- 了解FMA性能
- 与天真计算相比,FMA性能