web-dev-qa-db-ja.com

コンパイル時に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」は、ナイツコーナーベクトル命令最適化の略です。 FFTWなどのライブラリは、これらの新しい命令の最適化を検出/利用します。

49
Baptiste Wicht

ほとんどのコンパイラは自動的に以下を定義します:

__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)から利用可能なサポートを見ることができます。

騎士の着陸はここにあります:

$ 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
80
Paul R