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中。但是,程序员可以强制执行如下所示的对齐方式,这将在向量化之后产生两个对齐的访问模式(假设双精度数为 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现在,让我们看看使用(odd) 和i=6(even)的代码是什么样子...

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

或者

a[i+1] = b[i] * 3;会做[0x138] = [0x330] * 3

在这两种情况下,左侧或右侧都是对齐的,而另一个是未对齐的(对齐的访问将始终以十六进制的 0 结尾,未对齐的其他内容)。

现在......让我们有目的地错位a到 8 模 16 地址(比如 0x108,以保留我们的示例)。

i=3让我们看看使用(odd) 和i=6(even)的代码是什么样子...

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 回答