v4 シリーズのコンパイラーは、AMD Athlon や Intel Pentium/Core チップなどの最新の CPU でSIMDgcc
プロセッサーを使用してループを自動的にベクトル化できます。これはどのように行われますか?
2 に答える
元のページには、いくつかの例を含む、gcc を使用してループを自動的にベクトル化する方法の詳細が記載されています。
http://gcc.gnu.org/projects/tree-ssa/vectorization.html
例は素晴らしいものですが、最新の GCC でこれらのオプションを呼び出すための構文が少し変更されているようです。次を参照してください。
要約すると、次のオプションは SSE2 を使用する x86 チップで機能し、ベクトル化されたループのログを提供します。
gcc -O2 -ftree-vectorize -msse2 -mfpmath=sse -ftree-vectorizer-verbose=5
-msse も可能ですが、double や int ではなく、float を使用してループのみをベクトル化することに注意してください。(SSE2 は x86-64 のベースラインです。32 ビット コード-mfpmath=sse
でも使用できます。これは 64 ビットではデフォルトですが、32 ビットではありません。)
GCC の最新バージョンでは有効-ftree-vectorize
に-O3
なっているので、GCC4.x 以降ではそれを使用してください。
gcc -O3 -msse2 -mfpmath=sse -ftree-vectorizer-verbose=5
(Clang は で自動ベクトル化を有効にし-O2
ます。ICC のデフォルトは最適化有効 + 高速計算です。)
以下のほとんどは、新しい回答を書いたばかりの Peter Cordes によって書かれました。時間の経過とともに、コンパイラが変更されると、オプションとコンパイラの出力も変更されます。ここで詳細に追跡する価値があるかどうかは完全にはわかりません. コメント? - 著者
コンパイルしているハードウェアでサポートされている命令セット拡張機能も使用し、それに合わせて調整するには、-march=native
.
リダクション ループ (配列の合計など) には、OpenMP が必要になるか-ffast-math
、FP 演算を連想として扱い、ベクトル化する必要があります。 なしのスカラーであるリダクション (配列の合計) を含むGodbolt コンパイラ エクスプローラーの例-O3 -march=native -ffast-math
-ffast-math
。(まあ、GCC8 以降では SIMD ロードを実行し、それをスカラー要素にアンパックします。これは、単純な展開に対して無意味です。ループは、1 つのaddss
依存関係チェーンのレイテンシでボトルネックになります。)
必要ない場合もありますが-ffast-math
、-fno-math-errno
gcc インライン数学関数を支援し、sqrt
and/or rint
/を含むものをベクトル化することができますnearbyint
。
その他の便利なオプションには、-flto
(ファイル間のインライン化、定数伝播などのリンク時の最適化) および/またはプロファイルに基づく最適化-fprofile-generate
/ 現実的な入力によるテスト実行 / が含まれ-fprofile-use
ます。PGO は、「ホット」ループのループ展開を有効にします。-O3 でもデフォルトでオフになっている最新の GCC では。
gimple (GCC の中間表現) pass がありpass_vectorize
ます。このパスは、gimple レベルでの自動ベクトル化を有効にします。
自動ベクトル化 (GCC V4.4.0) を有効にするには、次の手順を実行する必要があります。
- ターゲット アーキテクチャごとに、ベクトル内の単語数に言及します。これは、マクロを定義することで実行できます
UNITS_PER_SIMD_WORD
。 - 可能なベクトル モードは、通常、別のファイルで定義する必要があります
<target>-modes.def
。このファイルは、マシンの説明を含む他のファイルが存在するディレクトリに存在する必要があります。(構成スクリプトに従って。スクリプトを変更できる場合は、ファイルを任意のディレクトリに配置できます)。 ターゲット アーキテクチャごとのベクトル化で考慮されるモード。同様に、4 つの単語が 1 つのベクトルを構成するか、8 つのハーフ ワードが 1 つのベクトルを構成し、2 つのダブル ワードが 1 つのベクトルを構成します。この詳細は、
<target>-modes.def
ファイルに記載する必要があります。例えば:VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI /
VECTOR_MODES (INT, 16); / V16QI V8HI V4SI V2DI /
VECTOR_MODES (FLOAT, 8); / V4HF V2SF */ポートを構築します。ベクトル化は、コマンド ライン オプションを使用して有効にすることができます
-O2 -ftree-vectorize
。