ダブルおよびffast-mathの自動ベクトル化
-
27-09-2019 - |
質問
なぜ使用することが必須です -ffast-math
G ++でループのベクトル化を実現する double
s?私は好きではありません -ffast-math
精度を失いたくないからです。
解決
必ずしも精度を失うわけではありません -ffast-math
. 。それはの取り扱いにのみ影響します NaN
, Inf
など、および操作が実行される順序。
GCCに計算を並べ替えたり簡素化したりしたくない特定のコードがある場合は、変数を使用して使用しているとマークできます。 asm
声明。
たとえば、次のコードは丸め操作を実行します f
. 。ただし、2つ f += g
と f -= g
操作はGCCによって最適化される可能性があります:
static double moo(double f, double g)
{
g *= 4503599627370496.0; // 2 ** 52
f += g;
f -= g;
return f;
}
x86_64では、これを使用できます asm
GCCにその最適化を実行しないように指示する声明:
static double moo(double f, double g)
{
g *= 4503599627370496.0; // 2 ** 52
f += g;
__asm__("" : "+x" (f));
f -= g;
return f;
}
残念ながら、各アーキテクチャにこれを適応させる必要があります。 PowerPCで使用します +f
それ以外の +x
.
他のヒント
ベクトル化は、あなたが異なる結果を持っている可能性があることを意味するか、または浮遊点信号/例外を逃すことを意味する可能性があるためです。
32ビットx86をコンパイルしている場合、GCCとG ++のデフォルトでx87を使用することにデフォルトで、64ビットでdefault sseになりますが、x87は同じ計算に対して異なる値を生成するため、G ++はありません。使用しない限り、同じ結果が得られることを保証できない場合は、ベクトル化を検討します -ffast-math
または、それがオンになっているフラグの一部。
基本的には、ベクトル化されたコードのフローティングポイント環境に帰着します。非ベクトル化コードのコードと同じではない場合があります。
-fno-math-errno -fno-trapping-math -fno-signaling-nans -fno-rounding-math
ただし、最初にこれらのオプションを調べて、プログラムの正確性に影響を与えないようにしてください。 -ffinite-math-only
助けになるかもしれません
なぜなら -ffast-math
有効にします オペランドの並べ替え これにより、多くのコードをベクトル化できます。
たとえば、これを計算します
sum = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + … a[99]
コンパイラはそうです 必要 追加するために 順次 それなし -ffast-math
, 、フローティングポイント数学は通勤でも連想的でもないからです。
それが同じ理由です コンパイラが最適化できない理由 a*a*a*a*a*a
に (a*a*a)*(a*a*a)
それなし -ffast-math
つまり、非常に効率的な水平ベクトルが追加されない限り、ベクトル化が利用できないことを意味します。
ただし、場合 -ffast-math
有効になっていると、式を計算できます このような (見る A7. Auto-Vectorization
)
sum0 = a[0] + a[4] + a[ 8] + … a[96]
sum1 = a[1] + a[5] + a[ 9] + … a[97]
sum2 = a[2] + a[6] + a[10] + … a[98]
sum3 = a[3] + a[7] + a[11] + … a[99]
sum’ = sum0 + sum1 + sum2 + sum3
これで、コンパイラは各列を並列に追加することで簡単にベクトル化でき、最後に水平方式の追加を実行できます。
します
sum’ == sum
?場合にのみ(a[0]+a[4]+…) + (a[1]+a[5]+…) + (a[2]+a[6]+…) + ([a[3]+a[7]+…) == a[0] + a[1] + a[2] + …
これは、常に順守しない連想性の下に保持されます。指定/fp:fast
この簡単な計算のために、コンパイラがコードをより速く実行するように変換して、最大4倍高速に実行できます。あなたは速いですか、それとも正確ですか? -a7。自動ベクトル化
によって有効になる場合があります -fassociative-math
GCCのフラグ