インテル® AVX をサポートする第 2 および第 3 世代インテル® Core™ プロセッサー・ファミリー向けに手動でコードを配置するには

特集

手動プロセッサー・ディスパッチ機能を使用すると、指定したインテル・プロセッサーで実行する複数バージョンの関数を記述することができます。インテル・プロセッサーのタイプはランタイムで判定され、該当する関数が実行されます。この機能は、IA-32 と インテル 64 をサポートするインテル・プロセッサーでのみ利用できます。互換プロセッサーや IA-64 アーキテクチャーでは利用できません。手動プロセッサー・ディスパッチ機能を使用してビルドされたアプリケーションは、インテル・プロセッサー向けに高度な最適化ができます。

__declspec(cpu_ dispatch(cpuid,cpuid,…))  構文で、ディスパッチするターゲット・プロセッサーのリストと、空の関数ボディー (関数スタブ) を記述します。

__declspec(cpu_specific(cpuid))  構文で、対象のプロセッサー・タイプで実行する関数を記述します。上記の cpu_dispatch で指定した cpuid 分の関数が必要です。

次の表は、cpuid に指定可能なキーワードの一覧です (大文字と小文字は区別しません):

CPUID キーワード

対象プロセッサー

core_4th_gen_avx

インテル® アドバンスト・ベクトル拡張 2 (インテル® AVX2) をサポートする将来のプロセッサー向け (コード名 Haswell)

core_3rd_gen_avx

インテル® アドバンスト・ベクトル拡張  (インテル® AVX) をサポートする第3世代インテル® Core™ プロセッサー・ファミリー (コード名 Ivy Bridge)

core_2nd_gen_avx

インテル® アドバンスト・ベクトル拡張  (インテル® AVX) をサポートする第2世代インテル® Core™ プロセッサー・ファミリー (コード名 Sandy Bridge)

core_aes_pclmulqdq

インテル® AES-NI (Advanced Encryption Standard Instruction Setとキャリーなしの乗算命令) をサポートするインテル® Core™ プロセッサー・ファミリー (コード名 Westmere)

core_i7_sse4_2

インテル® SSE4 高効率で高速な文字列処理命令 (SSE4.2) をサポートする、インテル® Core™ プロセッサー・ファミリー (コード名 Nehalem)

atom

インテル® Atom™ プロセッサー・ファミリー

core_2_duo_sse4_1

インテル® SSE4 ベクトル化とメディア・アクセラレーター命令 (SSE4.1) をサポートするインテル® 45nm Hi-K 世代のインテル® Core™ プロセッサー・ファミリー (コード名 Penryn)

core_2_duo_ssse3

インテル® サプリメンタル・ストリーミングSIMD拡張3 (SSSE3) をサポートするインテル® Core™2 Duo プロセッサー・ファミリーとインテル® Xeon® プロセッサー・ファミリー

pentium_4_sse3

インテル® ストリーミングSIMD拡張3 (SSE3) をサポートするインテル® Pentium 4 プロセッサー・ファミリー、インテル® Core™ Duo プロセッサー、インテル® Core™ Solo プロセッサー

pentium_4

インテル® Pentium 4 プロセッサー

pentium_m

インテル® Pentium M プロセッサー

pentium_iii

インテル® Pentium III プロセッサー

generic

他の IA-32 やIntel 64 プロセッサー、もしくは、インテル製以外の互換プロセッサー

リストのキーワード以外のインテル・プロセッサーが認識されると “generic” バージョンの関数が実行されます。また、インテル製以外の互換プロセッサーで実行することを意図する場合、”generic” バージョンにコードを記述する必要があります。”generic” 関数の最適化の度合いとプロセッサー機能は、それを意図するプログラマーの制御下にあります。

次の例は、cpu_dispatch と cpu_specific を利用して、インテル® AVX をサポートする第3世代インテル® Core™ プロセッサー、インテル® Atom™ プロセッサー、そしてその他のインテル・プロセッサーと互換プロセッサー向けのコードを記述する例です。各プロセッサー固有の関数には、プロセッサー固有の組み込み関数が含まれる場合や、プロセッサー固有のコンパイルオプションでコンパイルされた別ファイルの関数を呼び出すことができます。プロセッサー固有のコンパイルオプションについては以下を参照ください。

__declspec(cpu_dispatch(core_3rd_gen_avx,  atom, generic))

Void func(int num){
// スタブ関数は空でなければいけません。
}

__declspec(cpu_specific(core_3rd_gen_avx)){
// インテル® AVXをサポートする第3世代インテル® Core™ プロセッサー向けのコードを記述
}

__declspec(cpu_specific(atom)){
// インテル® Atom™ プロセッサー向けのコードを記述
}

__declspec(cpu_specific(generic)){
// 汎用コードを記述
}

プロセッサー固有機能の問い合わせ

プロセッサー固有機能が利用可能かどうか判断するため、ソースレベルで動的にプロセッサーに問い合わせます。この組込み関数はプロセッサーベンダーのチェックは行わないため、機能があるかどうかだけを確認できます。つまり、互換プロセッサーでも利用できます。

構文

extern int _may_i_use_cpu_feature(unsigned __int64);

引数

unsigned __int64

1 つまたは複数の CPUID 機能を表す符号なし __int64 ビット。次の引数を使用できます。

_FEATURE_GENERIC_IA32

_FEATURE_FPU

_FEATURE_CMOV

_FEATURE_MMX

_FEATURE_FXSAVE

_FEATURE_SSE

_FEATURE_SSE2

_FEATURE_SSE3

_FEATURE_SSSE3

_FEATURE_SSE4_1

_FEATURE_SSE4_2

_FEATURE_POPCNT

_FEATURE_MOVBE

_FEATURE_PCLMULQDQ

_FEATURE_AES

_FEATURE_F16C

_FEATURE_AVX

_FEATURE_RDRND

_FEATURE_FMA

_FEATURE_BMI

_FEATURE_LZCNT

説明

この組込み関数は、指定された機能が利用可能かどうか、実行中のプロセッサーに問い合わせます。このチェックは、ソースの呼び出し位置で動的に実行されます。この組み込み関数は、インクルードファイル “immintrin.h” に定義されています。次に例を示します。

if (_may_i_use_cpu_feature(_FEATURE_SSE4_2)) {
                   // インテル® SSE4.2 固有の組込み関数を使用できます
}
Else {
                   // 汎用コードを使用します
}

この場合、“_may_i_use_cpu_feature” 組込み関数は、コードを実行中のプロセッサーがインテル® SSE4.2 に対応しているかどうかを動的にチェックし、対応している場合は true (そうでない場合は false) を返します。“_may_i_use_cpu_feature” 組込み関数では、次のように、引数内で複数の機能を問い合わせできます。

if (_may_i_use_cpu_feature(_FEATURE_SSE |
                                         _FEATURE_SSE2 |
                                         _FEATURE_SSE3 |
                                         _FEATURE_SSSE3 |
                                         _FEATURE_MOVBE) &&
                                !_may_i_use_cpu_feature(_FEATURE_SSE4_1)) {
printf(“\nこのコードは Atom プロセッサーで実行されています。”\n”);
} 

この組込み関数は、-m オプション (Linux) とは異なり、プロセッサーのベンダーはチェックしません。実行中のプロセッサーに問い合わせた機能があれば、true が返ります。

戻り値

実行中のマシンで指定された機能が利用可能かどうかを示す問い合わせの結果 true または false (1 または 0)。

ドキュメントには正式に反映されていませんが、第4世代インテル® Core™ プロセッサー・ファミリー (コード名Haswell) がサポートする、AVX2 の機能は “_FEATURE_AVX2” で問い合わせできます。

この組み込み関数呼び出しを含むコードが、インテル® Xeon Phi™ にオフロードされる場合の動作は、未定義となります。

関連記事:

AVX-SSE 切り替えペナルティーを回避する

コンパイラー最適化入門: 第6回 ベクトル化の裏技集

タイトルとURLをコピーしました