インテル® C++ コンパイラー XE 13.1 ユーザー・リファレンス・ガイド

要素関数

要素関数は、データ並列アルゴリズムを表現するための一般的な言語構造です。通常の C/C++ 関数として記述され、そのアルゴリズムはスカラー構文を使用して 1 つの要素に対する操作を指示します。1 つの要素に対する操作を行う場合は通常の C/C++ 関数として呼び出され、複数の要素に対する操作の場合はデータ並列コンテキストで呼び出されます。インテル® Cilk™ Plus では、データ並列コンテキストは配列として提供されます。

要素関数の動作

要素関数がある場合、コンパイラーは一度の呼び出しで複数の引数に対して操作が行えるようにそのショートベクトル形式を生成します。このショート・ベクトル・バージョンは、CPU にあるベクトル用のインテル固有アーキテクチャー (ISA) を活用することで、通常の実装で個別に操作を行った場合と同じぐらい高速に複数の操作を行うことができます。さらに、データセットが大きい場合、コンパイラーは関数の呼び出し時に要素関数の異なるコピーを異なるスレッド (またはワーカー) に割り当てて同時に実行します。 その結果、データ並列操作は、マルチコアで利用可能な並列性とベクトル用の ISA で利用可能な並列性の両方を活用して CPU で実行されます。

並列ループ (cilk_for ループまたはベクトル化された自動並列化ループ) の内側でショートベクトル関数が呼び出されると、ベクトルレベルの並列化とスレッドレベルの並列化の両方を達成できます。

要素関数の宣言

コンパイラーがショートベクトル関数を生成するようにコード中で指示する必要があります。

Windows*:

次のように、__declspec(vector (clauses)) 宣言を使用します。

__declspec(vector (clauses)) return_type elemental_function_name(arguments)

Linux* および OS X*:

次のように、__attribute__((vector (clauses))) 宣言を使用します。

__attribute__((vector (clauses))) return_type elemental_function_name(arguments)

vector 宣言の clauses には、次の値を使用することができます。

processor(cpuid)

cpuid には、次のいずれかの値を指定できます。

  • atom

  • mic

  • core_aes_pclmulqdq

  • core_i7_sse4_2

  • core_2_duo_sse4_1

  • core_2_duo_ssse3

  • core_2nd_gen_avx

  • core_3rd_gen_avx

  • pentium_4_sse3

  • pentium_4

  • pentium_m

vectorlength(n)

n は ベクトル長 (vl) です。 2 のべき乗の整数値で、2、4、8、または 16 でなければなりません。

vectorlength 節は、各ルーチンの呼び出し位置で、スカラー関数を n 回実行するのと同じ分の計算を実行するようにコンパイラーに指示します。

vectorlengthfor(datatype)

datatype は、次のいずれかのビルトイン型でなければなりません。そうでない場合の動作は不定です。

  • 整数型 (8、16、32、または 64 ビット)

  • ポインター型 (ポインターのサイズの整数として処理されます)

  • 浮動小数点型 (32 または 64 ビット)

  • 複素数型 (64 または 128 ビット)

vectorlengthfor 節を使用する場合、n は使用されるプロセッサーのベクトルレジスター/データ型のサイズに対応するデータ型として計算されます。 例えば、vectorlengthfor(float) は、インテル® SSE2 からインテル® SSE4.2 対応のターゲット・プロセッサー (128 ビットの XMM レジスターでパックド浮動小数点演算に対応) では n=4、インテル® AVX 対応のターゲット・プロセッサー (256 ビットの YMM レジスターでパックド浮動小数点演算に対応) では n=8 になります。 vectorlengthfor(int) は、インテル® SSE2 からインテル® AVX 対応のターゲット・プロセッサーで n=4 になります。

vectorlength 節と vectorlengthfor 節は、同時に両方を指定することはできません。

linear(param1:step1 [, param2:step2]…)

説明:

  • param はスカラー変数です。

  • step はコンパイル時の正の整数定数式です。

    linear 節は、シリアル実行においてルーチンの連続した呼び出しで、param1 の値は step1 ずつ、param2step2 ずつというように増分されるようにコンパイラーに指示します。 特定の変数に複数の step が指定されている場合は、コンパイル時にエラーが発生します。複数の linear 節は結合されます。

uniform(param [, param,]…)

param は、指定された関数の仮引数です。

uniform 節は、パフォーマンスを最適化するために、指定された引数の値をすべての反復にブロードキャストするようにコンパイラーに指示します。 複数の uniform 節は結合されます。

[no]mask

[no]mask 節は、ルーチンのマスク付きのベクトルバージョンを生成するようにコンパイラーに指示します。

既存の C/C++ 構文を使用して関数の中にこのコードを記述します。

並列コンテキストでの要素関数の呼び出し

通常、要素関数で仮パラメーターとしてスカラー引数が指定されている場合、その呼び出しは配列を提供します。この配列は、インテル® Cilk™ Plus の配列表記を使用して簡潔に提供することができます。また、_Cilk_for ループから要素関数を呼び出すこともできます。

次の例は、要素関数を使用して 2 つの大きな配列の加算を行い、その結果を別の配列に格納します。この例は、CPU のコアとベクトルで利用可能な並列性を活用しています。

Windows*:

//declaring the function body
__declspec((vector)) double ef_add (double x, double y){
  return x + y;
}
  
//invoking the function using array notations
a[:] = ef_add(b[:],c[:]);    //operates on the whole extent of the arrays a,b,c
a[0:n:s] = ef_add(b[0:n:s],c[0:n:s]); //use the full array notation construct to also specify n as an extend and s as a stride
  
//Use the _Cilk_for construct to invoke the elemental function in a data parallel context
_Cilk_for (j = 0; j < n; ++j) {
  a[j] = ef_add(b[j],c[j])
}

Linux* および OS X*:

//declaring the function body
__attribute__((vector)) double ef_add (double x, double y){
  return x + y;
}
  
//invoking the function using array notations
a[:] = ef_add(b[:],c[:]);    //operates on the whole extent of the arrays a,b,c
a[0:n:s] = ef_add(b[0:n:s],c[0:n:s]); //use the full array notation construct to also specify n as an extend and s as a stride
  
//Use the _Cilk_for construct to invoke the elemental function in a data parallel context
_Cilk_for (j = 0; j < n; ++j) {
  a[j] = ef_add(b[j],c[j])
}

_Cilk_for 呼び出し構文を使用するコードのみが利用可能なすべての並列性を使用できます。 通常の for ループからの要素関数の呼び出しおよび配列表記構文は、各反復でショートベクトル関数を呼び出しますが、この呼び出しはマルチコアを活用することなくシリアルループで行われます。

制限事項

次の言語構造は要素関数内で許可されていません。

関連情報


このヘルプトピックについてのフィードバックを送信