fma()
FMA のパフォーマンス ( in math.h
) と単純な乗算および浮動小数点演算の加算を比較しようとしています。テストは簡単です。繰り返し回数が多い場合は、同じ計算を繰り返します。正確な検査のために達成しなければならないことが2つあります。
- 時間のカウントに他の計算を含めるべきではありません。
- 単純な乗算と加算は 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;
}