Any*_*orn 8 memory optimization gcc pragma alignment
gcc是否具有内存对齐编译指示,类似于#pragma vector aligned
英特尔编译器?我想告诉编译器使用对齐的加载/存储指令优化特定的循环.为了避免可能的混淆,这不是结构包装.
例如:
#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
for (int a = 0; a < int(N); ++a) {
q10 += Ix(a,0,0)*Iy(a,1,1)*Iz(a,0,0);
q11 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,1,0);
q12 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,0,1);
q13 += Ix(a,1,0)*Iy(a,0,0)*Iz(a,0,1);
q14 += Ix(a,0,0)*Iy(a,1,0)*Iz(a,0,1);
q15 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,1,1);
}
Run Code Online (Sandbox Code Playgroud)
谢谢
Die*_*Epp 10
您可以通过使用typedef创建一个可以声明指针的过度对齐类型来告诉GCC指针指向对齐的内存.
这有助于gcc而不是clang7.0或ICC19,请参阅他们在Godbolt上发出的x86-64非AVX.(只有GCC将负载折叠到内存操作数中mulps
,而不是单独使用movups
).__builtin_assume_aligned
如果你想向GCC本身以外的GNU C编译器移植一个对齐承诺,你必须使用.
来自http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
typedef double aligned_double __attribute__((aligned (16)));
// Note: sizeof(aligned_double) is 8, not 16
void some_function(aligned_double *x, aligned_double *y, int n)
{
for (int i = 0; i < n; ++i) {
// math!
}
}
Run Code Online (Sandbox Code Playgroud)
这不会使aligned_double
16字节宽.这将使它与16字节边界对齐,或者更确切地说是数组中的第一个边界.看看我的计算机上的反汇编,一旦我使用了对齐指令,我就开始看到很多矢量操作.我目前正在使用Power架构计算机,因此它是altivec代码,但我认为这可以满足您的需求.
(注意:double
当我测试时,我没有使用,因为altivec不支持双浮点数.)
您可以在此处使用类型属性查看自动向量化的其他一些示例:http://gcc.gnu.org/projects/tree-ssa/vectorization.html
我用g ++版本4.5.2(Ubuntu和Windows)尝试了你的解决方案,并没有对循环进行矢量化.
如果删除了alignment属性,则使用未对齐的加载来对循环进行矢量化.
如果函数是内联的,那么可以在消除指针的情况下直接访问数组,然后使用对齐的加载进行矢量化.
在这两种情况下,alignment属性都会阻止矢量化.具有讽刺意味的是:"aligned_double*x"应该能够实现矢量化,但却恰恰相反.
哪个编译器报告了矢量化循环?我怀疑它不是gcc编译器?