手動 CPU ディスパッチ (IA-32 のみ)

特定のプロセッサーでのみ動作するコードを作成するには、手動 CPU ディスパッチを使用します。コードで cpu_specific および cpu_dispatch キーワードを使用すると、コンパイラーでサポートされているディスパッチ機能を使用して、プロセッサーの種類を検出することができます。

ターゲットのインテル(R) プロセッサー固有のコードを作成して、さらに他の IA-32 プロセッサーでもアプリケーションが正常に動作するようにするには、コードで __declspec(cpu_specific) および __declspec(cpu_dispatch) 構文を使用します。

手動 CPU ディスパッチは、インテル(R) Itanium(R) プロセッサーは認識しません

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

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

プロセッサー

cpuid引数

インテル(R) Pentium(R) プロセッサー

pentium

MMX(R) テクノロジー インテル Pentium プロセッサー

pentium_mmx

インテル Pentium Pro プロセッサー

pentium_pro

インテル Pentium II プロセッサー

pentium_ii

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

pentium_iii

インテル Pentium III (xmm レジスターを除く)

pentium_iii_no_xmm_regs

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

pentium_4

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

pentium_m

ストリーミング SIMD 拡張命令 3 (SSE3) をサポートするインテル Pentium 4 プロセッサー、インテル(R) Core(TM) Duo プロセッサー、インテル Core Solo プロセッサー

pentium_4_sse3

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

generic

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

cpuid-list構文

cpuid

cpuid-list、cpuid

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

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

次の例では、cpu_specific cpu_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.*/

}

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