我的工作自动向量化与海湾合作委员会。我不是在一个位置,使用内在属性或因客户的要求。 (我不能获取用户输入以支持矢量)

如果可以向量化阵列的对准信息是未知的,GCC调用关于“循环版本”一通。当循环矢量是在树上进行,将进行版本循环。当一个环被识别为向量化的,并且在数据对齐或数据依赖约束阻碍它,(因为它们不能在编译时被确定),那么该环的两个版本将生成。这些是环的与运行时检查对准或依赖执行哪个版本来控制沿所述向量化和非量化版本。

我的问题是我们如何来执行对齐?如果我发现一个循环,是量化的,我不应该产生环路的两个版本,因为缺少对齐信息。

例如。考虑下面的代码

short a[15]; short b[15]; short c[15];
int i;

void foo()
{
    for (i=0; i<15; i++)
    {
      a[i] = b[i] ;
    }
}

树转储(选项:-fdump树优化-ftree-矢量化)

<SNIP>
     vector short int * vect_pa.49;
     vector short int * vect_pb.42;
     vector short int * vect_pa.35;
     vector short int * vect_pb.30;

    bb 2>:
     vect_pb.30 = (vector short int *) &b;
     vect_pa.35 = (vector short int *) &a;
     if (((signed char) vect_pa.35 | (signed char) vect_pb.30) & 3 == 0)    ;; <== (A)
       goto <bb 3>;
     else
       goto <bb 4>;

    bb 3>:
</SNIP>

目前的量化代码“BB 3”版本被生成。在没有向量化“BB 4”代码被生成。这些通过检查对齐(声明“A”)来完成。现在不使用内联函数和其他属性,我应该怎么只得到量化代码(如果没有这个运行时对齐检查。)

有帮助吗?

解决方案

如果被静态分配有问题的数据,则可以使用__align__属性,该属性GCC支持指定应当对准到必要的边界。如果要动态地分配这些阵列,则可以通过该对准值过度分配,然后凸块返回的指针到所需的取向。

您还可以,如果你是一个支持它的系统上使用posix_memalign()功能。最后,注意malloc()将始终分配内存对齐到最大的内置类型,双一般在8个字节的大小。如果你并不需要比这更好的,然后malloc应该足够了。

修改的:如果您修改分配代码,迫使该支票是真实的(即overallocate,如上述建议),编译器应该不会conditionalizing循环代码效劳。如果您需要对齐的8字节边界,因为它似乎,这将是像a = (a + 7) & ~3;

其他提示

我得到循环的只有一个版本,使用确切的代码与这些选项:gcc -march=core2 -c -O2 -fdump-tree-optimized -ftree-vectorize vec.c

我的GCC的版本是gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu8)

GCC是在这里做的很漂亮。它迫使阵列ab为16字节对齐。它不这样做,以c,大概是因为c再也不能在量化循环使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top