2010-04-21 72 views
7

gcc是否有内存对齐编译指示,类似#pragma vector aligned英特尔编译器中? 我想告诉编译器使用对齐的加载/存储指令来优化特定的循环。为了避免可能的混淆,这不是关于结构打包。gcc内存对齐编译指示

e.g:

#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); 
     } 

感谢

回答

8

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! 
    } 
} 

这不会使aligned_double 16字节宽。这只会使它对齐到一个16字节的边界,或者更确切地说是数组中的第一个边界。看看我的电脑上的反汇编,只要我使用对齐指令,我开始看到很多矢量ops。目前我正在使用Power架构计算机,所以它是altivec代码,但我认为这是你想要的。

(注:我没有使用double当我测试了这一点,因为那里的AltiVec不支持双浮筒)

您可以看到使用类型自动向量化的其他一些例子属性在这里:http://gcc.gnu.org/projects/tree-ssa/vectorization.html

+0

既不。我有数组,该编译器无法确定对齐方式。 我必须具体说明使用对齐的加载和存储。它不会是编译器选项,它必须是编译指示,对每个单独的循环进行矢量化。 – Anycorn 2010-04-21 23:46:46

+0

为什么你不能在数组上使用可变属性? – 2010-04-21 23:47:18

+0

数组是malloced的,加上数组的结构相当复杂。 具体来说,它是一个四维张量 – Anycorn 2010-04-21 23:48:51

5

我用g ++版本4.5.2(包括Ubuntu和Windows)尝试了你的解决方案,并且它确实向传递了向量化循环的代码

如果删除了alignment属性,那么它会使用未对齐的加载矢量化循环。

如果函数被内联,以便可以在指针消除的情况下直接访问数组,那么它就是使用对齐的加载进行矢量化的。

在这两种情况下,alignment属性都会防止向量化。这颇具讽刺意味:“aligned_double * x”本来是为了实现矢量化,但它却是相反的。

哪个编译器报告过矢量化循环?我怀疑它不是一个gcc编译器?

1

GCC是否有内存对齐编译,类似的#pragma矢量对准

它看起来像GCC的新版本有__builtin_assume_aligned

内置功能:void * __builtin_assume_aligned (const void *exp, size_t align, ...)

该函数返回其第一个参数,并允许编译器假定返回的指针至少对齐字节对齐。 这个内置参数可以有两个或三个参数,如果有三个参数, 第三个参数应该是整数类型,如果它不是零,那么 表示不对齐偏移量。例如:

void *x = __builtin_assume_aligned (arg, 16); 

意味着,编译器可以假定X,设定为精氨酸,是至少16字节对齐,而:

void *x = __builtin_assume_aligned (arg, 32, 8); 

意味着,编译器可以假定为X,设定为arg,(char *)x - 8是32字节对齐的。

根据大约2010年Stack Overflow的其他一些问题和答案,似乎内置在GCC 3和GCC 4早期不可用。但我不知道截止点在哪里。