【发布时间】:2015-05-26 22:51:56
【问题描述】:
我正在尝试比较 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 三级缓存)
我的代码
#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;
}
【问题讨论】:
-
我用:
g++ test.cpp -mfma -O0 -o test编译,结果显示两者都大约 250 毫秒。 -
带有
-O0的基准毫无价值。 -
比较
-O0与-O2或-O3的汇编程序,看看删除了多少垃圾。尤其是跳跃、装载和存储,这可能很昂贵。你的测试有点臃肿。