1. ホーム
  2. gcc

コンパイル時にSSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVIの可用性を検出するにはどうしたらいいですか?

2023-10-14 11:25:06

質問

私はいくつかの行列計算を最適化しようとしていて、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 の代わりに .