ここでは、コードのベクトル化に役立つ特定の C++ 言語機能について説明します。
SIMD ベクトル化機能は、インテル製マイクロプロセッサーおよび互換マイクロプロセッサーの両方で利用可能です。ベクトル化により呼び出されるライブラリー・ルーチンは、互換マイクロプロセッサーよりもインテル製マイクロプロセッサーにおいてより優れたパフォーマンスが得られる可能性があります。また、ベクトル化は、/arch や /Qx (Windows*) または -m や -x (Linux* および OS X*) などの特定のオプションによる影響を受けます。
__declspec(align(n)) 宣言を使用することで、ハードウェアのアライメント条件を変更できます。
restrict 指示子と自動ベクトル化ヒントは、語彙スコープ、データの依存性、両義性の解決による書き方に関する問題を処理します。
SIMD 機能のプラグマによりループのベクトル化を実行できます。
__attribute__(vector) と __attribute__(vector(clauses)) 宣言は、ユーザー指示による関数およびループをベクトル化するのに使用できます。
SIMD の使用では、vector 関数はベクトル化されるループから呼び出されます。
この関数はループの一部として、ベクトル演算に実装されなければなりません。
配列表記 (アレイ・ノーテーション) の C/C++ 拡張の map 演算は、実装手法を表現していない汎用データ並列セマンティクスを提供するために定義できます。
配列表記では、問題のサイズにかかわらず同じ演算を記述し、演算の実装に SIMD、ループ、タスキングを組み合わせて最適な構造が使用されるようにできます。
これらのセマンティクスにより、さらに精巧なプログラミングを選択し、推奨される並列実行とベクトル実行を行うため、タスク構造と配列演算の両方を使用して 2 レベルで単一の次元演算を表現できます。
タスク並列処理の実装は呼び出し位置で行われるのに対して、vector 宣言の使用モデルでは、関数用に生成されたコードは実際に配列の小さなセクション (vectorlength または vectorlengthfor) を値で受け取り、SIMD 並列処理を活用します。
次の表は、コードのベクトル化に役立つ言語機能をまとめたものです。
言語機能
|
説明
|
__declspec(align(n))
|
変数を n バイト境界にアライメントするようにコンパイラーに指示します。
変数のアドレスは address mod n=0 です。
|
__declspec(align(n,off))
|
各 n バイト境界内でオフセットだけ離して変数を n バイト境界にアライメントするようにコンパイラーに指示します。
変数のアドレスは address mod n=off です。
|
__attribute__(vector)
|
呼び出し位置で map 演算と組み合わせて、データ並列セマンティクスを提供します。
並列コンテキスト内に vector 宣言の複数のインスタンスが起動する場合、順次に実行されません。
|
__attribute__(vector(clauses))
|
呼び出し位置で map 演算と組み合わせて、次の節の値とともにデータ並列セマンティクスを提供します。
processor 節: processor(cpuid)
vector length 節: vectorlength(n)
vector length for 節: vectorlenghtfor(datatype)
linear 節: linear(param1:step1 [, param2:step2]…)
uniform 節: uniform(param [, param,]…)
mask 節: [no]mask
並列コンテキスト内に vector 宣言の複数のインスタンスが起動する場合、順次に実行されません。
|
restrict
|
エイリアス仮定を行うとき一義化機構に柔軟性を持たせます。これによってベクトル化の度合いがより高くなります。
|
__assume_aligned(a,n)
|
配列 a が n バイト境界にアライメントされていると見なすようにコンパイラーに指示します。アライメント情報が取得できなかった場合に使用します。
|
自動ベクトル化ヒント
|
#pragma ivdep
|
ベクトル依存性が存在していると推定されてもそれを無視するようにコンパイラーに指示します。
|
#pragma vector {aligned|unaligned|always|temporal|nontemporal}
|
ループをベクトル化する方法を指定し、効率ヒューリスティックについては無視したほうが良いことを示します。assert キーワードを vector {always} プラグマとともに使用すると、コンパイラーの効率性ヒューリスティックはループがベクトル化できないことを示している旨のエラーメッセージを生成します。
#pragma ivdep を使用して、想定された依存性を無視してください。
|
#pragma novector
|
ループをベクトル化しないように指定します。
|
ユーザー指示によるプラグマ
|
#pragma simd
|
ループのベクトル化を実行します。
|