手動プロセッサー・ディスパッチ機能を使用すると、指定したインテル・プロセッサーで実行する複数バージョンの関数を記述することができます。インテル・プロセッサーのタイプはランタイムで判定され、該当する関数が実行されます。この機能は、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™ プロセッサー、そしてその他のインテル・プロセッサーと互換プロセッサー向けのコードを記述する例です。各プロセッサー固有の関数には、プロセッサー固有の組み込み関数が含まれる場合や、プロセッサー固有のコンパイルオプションでコンパイルされた別ファイルの関数を呼び出すことができます。プロセッサー固有のコンパイルオプションについては以下を参照ください。
- インテル® C++ コンパイラーのベクトル化ガイド
- インテル® SSE およびインテル® AVX 世代 (SSE2、SSE3、SSSE3、ATOM_SSSE3、SSE4.1、SSE4.2、ATOM_SSE4.2、AVX、AVX2、AVX-512) 向けのインテル® コンパイラー・オプションとプロセッサー固有の最適化
__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™ にオフロードされる場合の動作は、未定義となります。