【发布时间】:2016-09-28 03:36:59
【问题描述】:
我正在生成 sse/avx 指令,目前我必须使用未对齐的加载和存储。我对浮点/双精度数组进行操作,我永远不会知道它是否会对齐。因此,在对其进行矢量化之前,我希望有一个前循环和可能的后循环,它负责处理未对齐的部分。然后主矢量化循环在对齐的部分上运行。
但是我如何确定数组何时对齐?我可以检查指针值吗?前循环应该什么时候停止,后循环应该什么时候开始?
这是我的简单代码示例:
void func(double * in, double * out, unsigned int size){
for( as long as in unaligned part ){
out[i] = do_something_with_array(in[i])
}
for( as long as aligned ){
awesome avx code that loads operates and stores 4 doubles
}
for( remaining part of array ){
out[i] = do_something_with_array(in[i])
}
}
编辑: 我一直在考虑。从理论上讲,指向第 i 个元素的指针应该可以被 2、4、16、32 整除(类似于 &a[i]%16==0)(取决于它是否为 double 以及它是 sse 还是 avx)。所以第一个循环应该覆盖不可分割的元素。
实际上我会尝试编译器编译指示和标志,看看编译器会产生什么。如果没有人给出好的答案,我会在周末发布我的解决方案(如果有的话)。
【问题讨论】:
-
您是否查看过自动矢量化编译器(如
gcc或clang)为处理可能的错位而生成的代码?我怀疑你不太清楚自己在做什么。 -
是的,将数组衰减为一个指针并对它进行算术运算将帮助您确定它是否在一个很好的对齐地址上。 但是... 检查没有帮助。如果第一个元素的地址没有很好地对齐,那么 all 元素的地址可能是未对齐的,或者至少是许多或大部分元素的地址。一个更好的想法可能是使用动态分配并添加一个初始填充以确保您有一个对齐的“数组”。
-
@JoachimPileborg:我认为问题是关于矢量指令的数据未对齐,在这种情况下,矢量的各个元素是对齐的。
-
@JoachimPileborg - 你所描述的情况不会自然发生,因为数组是根据底层数据类型对齐的 - 所以
double数组无论如何都是 8 字节对齐的。因此,根据 EOF 的评论,它实际上是关于每个单独 SIMD 指令(无论是 128 位还是 256 位或 512 位)中元素的布局。 -
这是我对这个问题的理解。请注意,在许多情况下,“首选”应改为“必需”——如果您尝试使用未对齐的内存,则会出现大量 AVX 指令段错误。
标签: c++ c x86 vectorization sse