来自英特尔的 Compiler Autovectorization Guide有一个我不明白的与对齐相关的例子。代码是
double a[N], b[N];
...
for(i = 0; i < N; i++)
a[i+1] = b[i] * 3;
它说
If the first element of both arrays is aligned at a 16-byte boundary, then either an unaligned load of elements from b or an unaligned store of elements into a, has to be used after vectorization. However, the programmer can enforce the alignment shown below, which will result in two aligned access patterns after vectorization (assuming an 8-byte size for doubles)
_declspec(align(16, 8)) double a[N];
_declspec(align(16, 0)) double b[N];
如何查看矢量化后错位的位置?对齐方式不会取决于数组的大小吗?
最佳答案
Hans Passant 基本上涵盖了所有正确的想法,但让我再解释一下:
假设 a
和 b
都对齐到 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
在这两种情况下,左侧或右侧对齐,而另一个未对齐(对齐的访问总是以十六进制的 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
两者都保持实际访问同时对齐和未对齐。
关于c++ - 自动矢量化对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18545920/