インテル® 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 には、次の値を使用することができます。
既存の 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 ループからの要素関数の呼び出しおよび配列表記構文は、各反復でショートベクトル関数を呼び出しますが、この呼び出しはマルチコアを活用することなくシリアルループで行われます。
制限事項
次の言語構造は要素関数内で許可されていません。
GOTO 文
16 以上の case 文を含む switch 文
class や struct に対する操作 (メンバーの選択を除く)
_Cilk_spawn キーワード
配列表記による並列化