問題タブ [fma]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - FMA のパフォーマンスを理解する
FMA パフォーマンスを計算する方法を理解したいと思います。ここの説明を見ると:
Skylake アーキテクチャの場合、命令にはLatency=4
とThroughput(CPI)=0.5
があるため、命令の全体的なパフォーマンスは命令4*0.5 = 2
ごとのクロックです。
したがって、最大 (ターボ) クロック周波数が 3 GHz であるかどうかを理解する限り、1 秒間に 1 つのコアで 1 500 000 000 命令を実行できます。
そうですか?もしそうなら、私がわずかに高いパフォーマンスを観察している理由は何ですか?
floating-point - clang/gcc は -ffast-math でのみ fma を生成します。なぜ?
icc 19 では、内積は fma 命令のループにコンパイルされます。clang と gcc では、fma は でのみ生成され-ffast-math
ます。
ただし、-ffast-math
IEEE 準拠は破られますが、fma は IEEE-754 2008 に完全に準拠しているため、 でコンパイルする必要がある場合は-ffast-math
、別の問題が発生します。
gcc と clang が なしで fma 命令を生成しないのはなぜ-ffast-math
ですか?
ゴッドボルト; コンパイラ フラグは-O3 -march=skylake-avx512
, +--ffast-math
です。
ieee-754 - FMA と単純な a*b+c の違いは?
FMA(3) の BSD ライブラリ関数マニュアルでは、「これらの関数は x * y + z を計算します」と述べています。
では、FMA と x * y + z を実行する素朴なコードの違いは何でしょう? また、ほとんどの場合、FMA のパフォーマンスが優れているのはなぜですか?
c++ - AVX2: 512 個の float 配列の内積の計算
私は SIMD 組み込み関数の完全な初心者です。
基本的に、私は AVX2 組み込み ( Intel(R) Core(TM) i5-7500T CPU @ 2.70GHz
) をサポートする CPU を持っています。std::vector<float>
sizeの 2 の内積を計算する最速の方法を知りたい512
です。
私はオンラインで掘り下げて、これとこれを見つけました。このスタックオーバーフローの質問は、次の関数を使用することを提案しています__m256 _mm256_dp_ps(__m256 m1, __m256 m2, const int mask);
。ただし、これらはすべて、内積を実行するさまざまな方法を示唆しています。何が正しい(そして最速の)方法なのかわかりませんそれ。
特に、サイズ 512 のベクトルに対して内積を実行する最速の方法を探しています (ベクトルのサイズが実装に影響することがわかっているため)。
ご協力ありがとうございました
編集 1-mavx2
: gcc フラグについても少し混乱しています。これらの AVX2 関数を使用する場合、コンパイル時にフラグを追加する必要がありますか? -OFast
また、単純な内積の実装を作成した場合、gccはこれらの最適化を実行できますか (gcc フラグを使用する場合など)。
編集2 誰かが時間とエネルギーを持っているなら、完全な実装を書いていただければ幸いです。他の初心者もこの情報を高く評価していると確信しています。
c++ - FFT アルゴリズムに FMA 命令を使用する
私は少しの C++ コードを持っていますが、これは時間の経過とともにいくぶん便利な FFT ライブラリになり、SSE および AVX 命令を使用してかなり高速に実行できるようになりました。確かに、それはすべて基数 2 のアルゴリズムのみに基づいていますが、それでも持ちこたえます。私の最近の悩みは、バタフライ計算を FMA 命令で動作させることです。基本的な基数 2 のバタフライは、4 回の乗算と 6 回の加算または減算で構成されます。簡単なアプローチでは、加算と減算の 2 つと 2 つの乗算を 2 つの FMA 命令に置き換える必要があり、数学的に同一のバタフライになりますが、明らかにこれを行うより良い方法があります。
作成者は、回転因子の虚数部分が実数部分で除算されるという条件で、10 個の add、sub、および mult のすべてを 6 個の FMA に置き換えます。テキストの一部に「cr1 != 0 であることに注意してください」と書かれています。一言で言えば、これは本質的に私の問題です。数学は、実際の回転がゼロの場合を除いて、すべての回転因子に対して宣伝されているように機能するようです。ゼロの場合、ゼロで割ることになります。ここで効率が絶対的に重要な場合、cr1 == 0 のときにコードを別のバタフライに分岐するのは良い選択肢ではありません。特に SIMD を使用して一度に複数の回転とバタフライを処理している場合、おそらく cr1 == の要素は 1 つだけです。 0. 私の直感がそうであるべきだと言っているのは、cr1 == 0 の場合、cr1 と ci1 はまったく別の値である必要があり、FMA コードは依然として正しい答えになるということです。しかし、私はこれを理解できないようです。私がそれを理解できれば、FMA バタフライの事前計算された回転因子を変更することは比較的簡単なことであり、もちろん、バタフライの開始時の除算演算を回避することもできます。