8

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

谢谢

4

3 回答 3

10

您可以告诉 GCC 一个指针指向对齐的内存,方法是使用 typedef 创建一个可以声明指针的过度对齐类型。

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

这不会使aligned_double16 字节宽。这只会使其与 16 字节边界对齐,或者更确切地说是数组中的第一个。看着我电脑上的反汇编,一旦我使用了对齐指令,我就开始看到很多向量操作。我目前正在使用 Power 架构计算机,所以它是 altivec 代码,但我认为这可以满足您的需求。

(注意:我在double测试时没有使用,因为 altivec 不支持双浮点数。)

您可以在此处查看使用类型属性的其他一些自动矢量化示例:http: //gcc.gnu.org/projects/tree-ssa/vectorization.html

于 2010-04-21T23:40:19.413 回答
5

我使用 g++ 4.5.2 版(Ubuntu 和 Windows)尝试了您的解决方案,但它没有循环进行矢量化。

如果对齐属性被删除,那么它将使用未对齐的负载对循环进行矢量化。

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

在这两种情况下,对齐属性都会阻止矢量化。这很讽刺:“aligned_double *x”本应启用矢量化,但结果恰恰相反。

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

于 2011-08-09T14:21:17.763 回答
3

gcc 是否有内存对齐 pragma,类似于 #pragma 向量对齐

看起来较新版本的 GCC 具有__builtin_assume_aligned

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

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

void *x = __builtin_assume_aligned (arg, 16);

意味着编译器可以假设设置为 arg 的 x 至少是 16 字节对齐的,而:

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

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

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

于 2017-03-27T06:24:42.247 回答