コンパイル時にSSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVIの可用性を検出するにはどうしたらいいですか?
質問
私はいくつかの行列計算を最適化しようとしていて、SSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVI [1] がコンパイラによって有効になっているか?理想的にはGCCとClangのために、しかし私はそれらの1つだけで管理することができます。
可能かどうかわからないので、もしかしたら自作のマクロを使うかもしれませんが、むしろ検知してユーザーに選択してもらうのがいいと思います。
[1] KCVI" は Knights Corner Vector 命令の最適化を意味します。FFTW のようなライブラリは、これらの新しい命令の最適化を検出し、利用します。
どのように解決するのですか?
ほとんどのコンパイラは自動的に定義します。
__SSE__
__SSE2__
__SSE3__
__AVX__
__AVX2__
などと、コマンドラインスイッチにしたがって記述します。gcc (または clang などの gcc 互換コンパイラ) では、このように簡単に確認することができます。
$ gcc -msse3 -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE_MATH__ 1
または
$ gcc -mavx2 -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __AVX__ 1
#define __AVX2__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
または、特定のプラットフォームでのデフォルトビルドのための事前定義されたマクロをチェックするためだけです。
$ gcc -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __SSE2_MATH__ 1
#define __SSE2__ 1
#define __SSE3__ 1
#define __SSE_MATH__ 1
#define __SSE__ 1
#define __SSSE3__ 1
より最近の Intel プロセッサは、モノリシックな命令セットではない AVX-512 をサポートしています。 以下の 2 つの例で、GCC (バージョン 6.2) から利用可能なサポートを見ることができます。
これは Knights Landing です。
$ gcc -march=knl -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __AVX__ 1
#define __AVX2__ 1
#define __AVX512CD__ 1
#define __AVX512ER__ 1
#define __AVX512F__ 1
#define __AVX512PF__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
こちらはSkylake AVX-512です。
$ gcc -march=skylake-avx512 -dM -E - < /dev/null | egrep "SSE|AVX" | sort
#define __AVX__ 1
#define __AVX2__ 1
#define __AVX512BW__ 1
#define __AVX512CD__ 1
#define __AVX512DQ__ 1
#define __AVX512F__ 1
#define __AVX512VL__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
Intel は追加の AVX-512 サブセットを開示しています ( ISA 拡張 ). GCC (バージョン 7) は、AVX-512 の 4FMAPS、4VNNIW、IFMA、VBMI および VPOPCNTDQ サブセットに関連するコンパイラー フラグとプリプロセッサー シンボルをサポートしています。
for i in 4fmaps 4vnniw ifma vbmi vpopcntdq ; do echo "==== $i ====" ; gcc -mavx512$i -dM -E - < /dev/null | egrep "AVX512" | sort ; done
==== 4fmaps ====
#define __AVX5124FMAPS__ 1
#define __AVX512F__ 1
==== 4vnniw ====
#define __AVX5124VNNIW__ 1
#define __AVX512F__ 1
==== ifma ====
#define __AVX512F__ 1
#define __AVX512IFMA__ 1
==== vbmi ====
#define __AVX512BW__ 1
#define __AVX512F__ 1
#define __AVX512VBMI__ 1
==== vpopcntdq ====
#define __AVX512F__ 1
#define __AVX512VPOPCNTDQ__ 1
SSE マクロは Visual C++ では動作しないことに注意してください。
を使用する必要があります。
_M_IX86_FP
の代わりに
.
関連
-
[解決済み】gcc makefileのエラー。"No rule to make target ..." (ターゲットを作るルールがない)
-
[解決済み] プリプロセッサー出力
-
[解決済み] 自作のmakefileを作成する【エラー255】。
-
[解決済み] cygwinにgccをインストールするにはどうしたらいいですか?
-
[解決済み] なぜGCCはa*a*a*a*aを(a*a*a)*(a*a*a)に最適化しないのでしょうか?
-
[解決済み】-Wl,-rpath -Wlがわかりません。
-
[解決済み] ビルドターゲットの外にgccのデバッグシンボルを生成する方法は?
-
[解決済み] MinGWとMSYSがコマンドラインから与えられたパス名を混乱させないようにする方法
-
[解決済み] 依存関係のある動的ライブラリとリンクする
-
GCCを使った警告メッセージの選択的削除
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] g++ 出力: ファイルが認識されません。ファイル形式が認識されない
-
[解決済み] プリプロセッサー出力
-
[解決済み] .ascizと.stringアセンブラディレクティブの違いは何ですか?
-
[解決済み] gccの-lpthreadオプション
-
[解決済み] LD_LIBRARY_PATH と LIBRARY_PATH の比較
-
[解決済み】すべてのgcc警告を無効にする
-
[解決済み] CMakeに新しいGCCのパスを指定する方法
-
[解決済み] gcc -ggdbとgcc -gの違いは何ですか?
-
[解決済み] rpathと-Lの違いは何ですか?
-
[解決済み] コマンドラインオプションの--start-groupと--end-groupとは何ですか?