ベクトル化はアライメントされたデータで実行する場合、より高速なコードを生成することができます。ここでは、Driver.c の 配列 a、b、x を 16 バイト境界にアライメントすることによりパフォーマンスを向上させます。このアライメントによって、ベクトル化はすべての配列に速度の遅いアライメントされていないロード命令ではなく、アライメント済みロード命令を使用して、アライメントのランタイムテストを回避することできます。ALIGNED マクロで aligned attribute キーワードを使用すると、Driver.c の a、b、x の宣言が変更されます。キーワードの構文は次のとおりです。
float array[30] __attribute__((aligned(base, [offset])));
この命令は、オフセットが "offset" (デフォルト=0) バイトの "base" バイト境界でアライメントされた配列を作成するようコンパイラーに指示します。次に例を示します。
FTYPE a[ROW][COLWIDTH] __attribute__((aligned(16)));
さらに、行列 a の行の長さが 16 バイトの倍数になるようにパディングする必要があります。a の各行は 16 バイトのアライメントになります。また、このアライメントによる利点を最大限に活かすには、#pragma vector aligned を使用して、Multiply.c の配列がアライメントされていると安全に仮定できることをベクトル化機能に知らせる必要があります。
#pragma vector aligned を使用する場合、ループのすべての配列またはサブ配列が確実に 16 バイトにアライメントされていなければなりません。そうでない場合、ランタイムエラーが発生することがあります。#pragma vector aligned を使用していなくても、データのアライメントによりパフォーマンスの利点は得られます。Multiply.c の ALIGNED マクロによるコードを参照してください。
インテル® AVX 命令セット向けにコンパイルする場合は、データを 32 バイト境界にアライメントしてください。パフォーマンスが向上することがあります。この場合、#pragma vector aligned は、コンパイラーにデータを 32 バイト境界にアライメントするよう指示します。
データを確実に一貫したアライメントにするには、ALIGNED マクロを追加した後、プログラムを再コンパイルしてください。-qopt-report=4 を使用して、更新された参照のレポートを確認できます。
icc -std=c99 -qopt-report=4 -qopt-report-phase=vec -D NOALIAS -D ALIGNED Multiply.c Driver.c -o MatVector
#pragma vector aligned 追加前の Multiply.optrpt:
ループの開始 Multiply.c(49,9) <ベクトル化のピールループ> ループの終了 ループの開始 Multiply.c(49,9) リマーク #15388: ベクトル化のサポート: 参照 a[i][j] にアラインされたアクセスが含まれています。[ Multiply.c(50,21) ] リマーク #15388: ベクトル化のサポート: 参照 x[j] にアラインされたアクセスが含まれています。[ Multiply.c(50,31) ] リマーク #15305: ベクトル化のサポート: ベクトル長 2 リマーク #15399: ベクトル化のサポート: アンロールファクターが 4 に設定されます。 リマーク #15309: ベクトル化のサポート: 正規化されたベクトル化のオーバーヘッド 1.031 リマーク #15300: ループがベクトル化されました。 リマーク #15442: すべてのループは剰余ループとして実行されます。 リマーク #15448: マスクなしアライン・ユニット・ストライド・ロード: 2 リマーク #15475: --- ベクトルのコストサマリー開始 --- リマーク #15476: スカラーコスト: 10 リマーク #15477: ベクトルコスト: 4.000 リマーク #15478: スピードアップの期待値: 2.380 リマーク #15488: --- ベクトルのコストサマリー終了 --- ループの終了 ループの開始 Multiply.c(49,9) <別の境界でアライメントされたベクトルループ> ループの終了 ループの開始 Multiply.c(49,9) <ベクトル化の剰余ループ> ループの終了
-D ALIGNED 追加後の Multiply.optrpt:
ループの開始 Multiply.c(49,9) リマーク #15388: ベクトル化のサポート: 参照 a[i][j] にアラインされたアクセスが含まれています。[ Multiply.c(50,21) ] リマーク #15388: ベクトル化のサポート: 参照 x[j] にアラインされたアクセスが含まれています。[ Multiply.c(50,31) ] リマーク #15305: ベクトル化のサポート: ベクトル長 2 リマーク #15399: ベクトル化のサポート: アンロールファクターが 4 に設定されます。 リマーク #15309: ベクトル化のサポート: 正規化されたベクトル化のオーバーヘッド 0.594 リマーク #15300: ループがベクトル化されました。 リマーク #15448: マスクなしアライン・ユニット・ストライド・ロード: 2 リマーク #15475: --- ベクトルのコストサマリー開始 --- リマーク #15476: スカラーコスト: 10 リマーク #15477: ベクトルコスト: 4.000 リマーク #15478: スピードアップの期待値: 2.410 リマーク #15488: --- ベクトルのコストサマリー終了 --- ループの終了 ループの開始 Multiply.c(49,9) <ベクトル化の剰余ループ> リマーク #15388: ベクトル化のサポート: 参照 a[i][j] にアラインされたアクセスが含まれています。[ Multiply.c(50,21) ] リマーク #15388: ベクトル化のサポート: 参照 x[j] にアラインされたアクセスが含まれています。[ Multiply.c(50,31) ] リマーク #15335: 剰余ループはベクトル化されませんでした: ベクトル化は可能ですが非効率です。オーバーライドするには vector always ディレクティブまたは -vec-threshold0 を使用してください。 リマーク #15305: ベクトル化のサポート: ベクトル長 2 リマーク #15309: ベクトル化のサポート: 正規化されたベクトル化のオーバーヘッド 2.417 ループの終了
ここで、実行ファイルを開始して、実行時間を記録してください。