手動で IA-32 およびインテル® 64 アーキテクチャー・プロセッサーを対象にする

手動のプロセッサー・ディスパッチを使用すると、cpu_specific キーワードと cpu_dispatch キーワードにより、実行時に IA-32 またはインテル® 64 アーキテクチャー・プロセッサーを認識でき、ターゲット・プロセッサーのみで実行するコードパスと、その他のプロセッサーで実行するコードパスを作成することができます。手動のプロセッサー・ディスパッチは、IA-64 アーキテクチャーをベースとしたプロセッサーは認識しません。

ターゲットのインテル® プロセッサー固有のコードを作成して、さらにほかの IA-32 またはインテル® 64 アーキテクチャー・プロセッサーでも正常に動作するよにするには、コードで __declspec(cpu_specific) および __declspec(cpu_dispatch) 構文を使用します。

これらの C++ キーワードの使用に関しての情報は、「アプリケーションのビルド」の「言語が混在したプログラミング」を参照してください。

これらのキーワードの一般的な構文は、次の引数を使用して関数宣言を変更します。

次の表は、cpuid の値を列挙したものです。

cpuid の引数

プロセッサー

core_i7_sse4_2

インテル® ストリーミング SIMD 拡張命令 4.2 (SSE4.2) 対応インテル® Core™ i7 プロセッサー

core_2_duo_sse4_1

ストリーミング SIMD 拡張命令 4 (SSE4) ベクトル化コンパイラー命令およびメディア・アクセラレーター命令対応インテル® 45nm Hi-k 次世代 インテル® Core™ マイクロアーキテクチャー・プロセッサー

core_2_duo_ssse3

インテル® Core™2 Duo プロセッサーおよびインテル® ストリーミング SIMD 拡張命令 3 補足命令 (SSSE3) 対応インテル® 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

インテル以外から提供されている x86 プロセッサー

次の表は、cpuid-list の構文を列挙したものです。

cpuid-list の構文

cpuid

cpuid-list、cpuid

属性は大文字と小文字の区別はありません。__declspec(cpu_dispatch) を宣言した関数本体は空でなければなりません。そして、これはスタブ (本体が空の関数) と呼ばれます。

手動プロセッサー・ディスパッチは、一部の種類のインライン化を無効にすることがあります。ほとんどの場合、作成されるコードと実行ファイルのサイズは大きくなります。追加の関数呼び出しが行われるため、パフォーマンスのオーバーヘッドがさらに増加することがあります。リリース前に、ターゲットとするすべてのプラットフォームでアプリケーションをテストしてください。手動ディスパッチを使用する前に、この機能を使用するメリットがデメリット (追加工数とパフォーマンス低下の可能性) よりも重要かどうかをよく考慮してください。

プロセッサー・ディスパッチ・サポートを実装するには、次のガイドラインに従ってください。

次の例では、cpu_specificcpu_dispatch の両方を含む手動ディスパッチの使用方法を示します。

#include <stdio.h>

#include <mmintrin.h>

/* Pentium processor function does not use intrinsics

   to add two arrays. */

__declspec(cpu_specific(pentium))

void array_sum1(int *result, int *a, int *b, size_t len)

{

  for (; len > 0; len--)

    *result++ = *a++ + *b++;

}

/* Implementation for a Pentium processor with MMX technology uses

   an MMX instruction intrinsic to add four elements simultaneously. */

__declspec(cpu_specific(pentium_MMX))

void array_sum2(int *result, int const *a, int *b, size_t len)

{

  __m64 *mmx_result = (__m64 *)result;

  __m64 const *mmx_a = (__m64 const *)a;

  __m64 const *mmx_b = (__m64 const *)b;

  for (; len > 3; len -= 4)

    *mmx_result++ = _mm_add_pi16(*mmx_a++, *mmx_b++);

  /* The following code, which takes care of excess elements, is not

     needed if the array sizes passed are known to be multiples of four. */

  result = (unsigned short *)mmx_result;

  a = (unsigned short const *)mmx_a;

  b = (unsigned short const *)mmx_b;

  for (; len > 0; len--)

    *result++ = *a++ + *b++;

}

__declspec(cpu_dispatch(pentium, pentium_MMX))

void array_sum3(int *result, int const *a, int *b, size_t len)

{

  /* Empty function body informs the compiler to generate the

     CPU-dispatch function listed in the cpu_dispatch clause. */

}