我正在生成sse/avx指令,目前我必须使用未对齐的加载和存储。我操作的是float/double数组,我永远不知道它是否对齐。因此,在向量化之前,我想要有一个预循环和可能的后循环,来处理未对齐的部分。然后主向量化循环在对齐的部分上操作。
但是如何确定数组何时对齐?我可以检查指针值吗?预循环应该在何时停止,后循环应该在何时开始?
这是我的简单代码示例:
但是如何确定数组何时对齐?我可以检查指针值吗?预循环应该在何时停止,后循环应该在何时开始?
这是我的简单代码示例:
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(取决于它是双精度还是SSE或AVX)整除。因此,第一个循环应该覆盖那些不能被整除的元素。
实际上,我将尝试使用编译器pragma和标志来查看编译器生成了什么。如果没有人给出好的答案,我将在周末发布我的解决方案(如果有的话)。
gcc
ж€–clang
иү™ж ·зљ„и‡ҒеЉЁеђ‘й‡ЏеЊ–зә–иҮ‘е™Ёдёғ处理еЏҮиѓҢзљ„жњҒеҮ№йҢђжѓ…况生成的д»Әз Ѓеђ—пәџж€‘жЂЂз–‘дҢ 并дёҚе®Ње…Ёдғ†и§Әи‡Ғе·±жӘењЁеЃљд»Ђд№€гЂ‚ - EOFdouble
数组无论如何都将是 8 字节对齐的。因此,根据 EOF 的评论,这实际上是关于每个单独的 SIMD 指令内元素的布局(无论是 128 位、256 位还是 512 位)。 - Smeeheey__builtin_assume_aligned
或任何其他东西,因此gcc必须假定其中一个或两个指针是不对齐的。我忘记了gcc更喜欢对齐输入还是输出指针。如果输出对齐而输入不对齐,则无法执行对齐加载和对齐存储(除了palignr
之外,在Nehalem及更高版本中,当它们跨越缓存行时,未对齐的存储只会变慢)。 - Peter Cordes