1

Intel のCompiler Autovectorization Guideから、私が理解できないアライメントに関連する例があります。コードは

double a[N], b[N];
...
for(i = 0; i < N; i++)
  a[i+1] = b[i] * 3;

そしてそれは言う

両方の配列の最初の要素が 16 バイト境界でアラインされている場合、ベクトル化の後に、bからのアラインされていない要素のロードまたはaへの要素のアラインされていないストアのいずれかを使用する必要があります。ただし、プログラマーは以下に示すアライメントを強制することができます。これにより、ベクトル化後に 2 つのアライメントされたアクセス パターンが生成されます (double のサイズが 8 バイトであると仮定)。

_declspec(align(16, 8)) double a[N];
_declspec(align(16, 0)) double b[N];

ベクトル化後にミスアライメントが発生する場所を確認する方法は? アラインメントは配列のサイズに依存しませんか?

4

1 に答える 1

1

Hans Passant は基本的にすべての適切なアイデアを網羅していますが、もう少し説明させてください。

abは両方とも 16 バイトに揃えられています。例として、アドレス 0x100 と 0x200 があるとします。

i=3さて、コードが(奇数) と (偶数)でどのように見えるか見てみましょうi=6...

a[i+1] = b[i] * 3;[0x120] = [0x318] * 3(i=3, sizeof double は 8 )

また

a[i+1] = b[i] * 3;しましょう[0x138] = [0x330] * 3

どちらの場合も、左側または右側のいずれかが整列されていますが、もう一方は整列されていません (整列されたアクセスは常に 16 進数の 0 で終了し、他の何かが整列されていません)。

さて... 意図的aに 8 モジュロ 16 のアドレスにミスアラインしてみましょう (この例を維持するために 0x108 とします)。

i=3コードが(奇数) と (偶数)でどのように見えるか見てみましょうi=6...

a[i+1] = b[i] * 3;[0x128] = [0x318] * 3(i=3, sizeof double は 8 )

また

a[i+1] = b[i] * 3;しましょう[0x140] = [0x330] * 3

両方とも、実際のアクセスのアライメントとミスアライメントを同時に維持します。

于 2013-08-31T20:48:11.340 に答える