< 目次

データのアライメントによりパフォーマンスを向上する

ベクトル化はアライメントされたデータで実行する場合、より高速なコードを生成することができます。ここでは、Driver.c の 配列 abx を 16 バイト境界にアライメントすることによりパフォーマンスを向上させます。このアライメントによって、ベクトル化はすべての配列に速度の遅いアライメントされていないロード命令ではなく、アライメント済みロード命令を使用して、アライメントのランタイムテストを回避することできます。ALIGNED マクロで __align declspec キーワードを使用すると、Driver.cabx の宣言が変更されます。キーワードの構文は次のとおりです。

__declspec(align(16)) float array[30];

この命令は、オフセットが "offset" (デフォルト=0) バイトの "base" バイト境界でアライメントされた配列を作成するようコンパイラーに指示します。次に例を示します。

__declspec(align(16)) FTYPE a[ROW][COLWIDTH];

さらに、行列 a の行の長さが 16 バイトの倍数になるようにパディングする必要があります。a の各行は 16 バイトのアライメントになります。また、このアライメントによる利点を最大限に活かすには、#pragma vector aligned を使用して、Multiply.c の配列がアライメントされていると安全に仮定できることをベクトル化機能に知らせる必要があります。

#pragma vector aligned を使用する場合、ループのすべての配列またはサブ配列が確実に 16 バイトにアライメントされていなければなりません。そうでない場合、ランタイムエラーが発生することがあります。#pragma vector aligned を使用していなくても、データのアライメントによりパフォーマンスの利点は得られます。Multiply.cALIGNED マクロによるコードを参照してください。

インテル® AVX 命令セット向けにコンパイルする場合は、データを 32 バイト境界にアライメントしてください。パフォーマンスが向上することがあります。この場合、#pragma vector aligned は、コンパイラーにデータを 32 バイト境界にアライメントするよう指示します。

/Qopt-report:4 を使用して、更新された参照のレポートを確認できます (プロジェクトのプロパティー・ページで [構成プロパティ] > [C/C++] > [Diagnostics [Intel C++] (診断 [インテル® C++])] を選択し、[Optimization Diagnostics Level (最適化診断レベル)][Level 4 (レベル 4) (/Qopt-report:4)] に設定します)。データを確実に一貫したアライメントにするには、ALIGNED プリプロセッサー定義を追加した後、プログラムをリビルドしてください。

#pragma vector aligned 追加前の Multiply.optrpt:

ループの開始 Multiply.c(49,9)
ベクトル化のピールループ
ループの終了

ループの開始 Multiply.c(49,9)
Multiply.c(50,13): リマーク #15388: ベクトル化のサポート: 参照 a[i][j] にアラインされたアクセスが含まれています。
Multiply.c(50,13): リマーク #15388: ベクトル化のサポート: 参照 x[j] にアラインされたアクセスが含まれています。
Multiply.c(49,9): リマーク #15305: ベクトル化のサポート: ベクトル長 2
Multiply.c(49,9): リマーク #15399: ベクトル化のサポート: アンロールファクターが 4 に設定されます。
Multiply.c(49,9): リマーク #15309: ベクトル化のサポート: 正規化されたベクトル化のオーバーヘッド 1.031
Multiply.c(49,9): リマーク #15300: ループがベクトル化されました。
Multiply.c(49,9): リマーク #15442: すべてのループは剰余として実行されます。
Multiply.c(49,9): リマーク #15448: マスクなしアライン・ユニット・ストライド・ロード: 2 
Multiply.c(49,9): リマーク #15475: --- ベクトルのコストサマリー開始 ---
Multiply.c(49,9): リマーク #15476: スカラーコスト: 10 
Multiply.c(49,9): リマーク #15477: ベクトルコスト: 4.000 
Multiply.c(49,9): リマーク #15478: スピードアップの期待値: 2.380 
Multiply.c(49,9): リマーク #15488: --- ベクトルのコストサマリー終了 ---
ループの終了

ループの開始 Multiply.c(49,9)
代替アライメントでベクトル化されたループ
ループの終了

ループの開始 Multiply.c(49,9)
ベクトル化の剰余ループ
ループの終了

プリプロセッサーの定義に ALIGNED を追加後の Multiply.optrpt:

ループの開始 Multiply.c(49,9)
Multiply.c(50,13): リマーク #15388: ベクトル化のサポート: 参照 a[i][j] にアラインされたアクセスが含まれています。
Multiply.c(50,13): リマーク #15388: ベクトル化のサポート: 参照 x[j] にアラインされたアクセスが含まれています。
Multiply.c(49,9): リマーク #15305: ベクトル化のサポート: ベクトル長 2
Multiply.c(49,9): リマーク #15399: ベクトル化のサポート: アンロールファクターが 4 に設定されます。
Multiply.c(49,9): リマーク #15309: ベクトル化のサポート: 正規化されたベクトル化のオーバーヘッド 0.594
Multiply.c(49,9): リマーク #15300: ループがベクトル化されました。
Multiply.c(49,9): リマーク #15448: マスクなしアライン・ユニット・ストライド・ロード: 2 
Multiply.c(49,9): リマーク #15475: --- ベクトル・コスト・サマリー開始 ---
Multiply.c(49,9): リマーク #15476: スカラーコスト: 10 
Multiply.c(49,9): リマーク #15477: ベクトルコスト: 4.000 
Multiply.c(49,9): リマーク #15478: スピードアップの期待値: 2.410 
Multiply.c(49,9): リマーク #15488: --- ベクトル・コスト・サマリー終了 ---
ループの終了

ループの開始 Multiply.c(49,9)
ベクトル化の剰余ループ
Multiply.c(50,13): リマーク #15388: ベクトル化のサポート: 参照 a[i][j] にアラインされたアクセスが含まれています。
Multiply.c(50,13): リマーク #15388: ベクトル化のサポート: 参照 x[j] にアラインされたアクセスが含まれています。
Multiply.c(49,9): リマーク #15335: 剰余ループはベクトル化されませんでした: ベクトル化は可能ですが、非効率です。オーバーライドするには vector always ディレクティブまたは /Qvec-threshold0 を使用してください。
Multiply.c(49,9): リマーク #15305: ベクトル化のサポート: vector length 2
Multiply.c(49,9): リマーク #15309: ベクトル化のサポート: normalized vectorization overhead 2.417
ループの終了

行番号および列番号は異なる場合があります。

ここで、実行ファイルを開始して、実行時間を記録してください。