带展开循环的矢量化

时间:2011-07-04 14:35:58

标签: c++ compiler-construction vectorization

我正在使用intel-cc编译一些C ++代码,并且使用-Wall选项它似乎是在渲染我的很多循环。我正在假设这对于现在的性能有好处。

现在我的问题是这个;如果不是for循环,我已经展开它,所以我们有例如

a[0] = b[0] + 1;
a[1] = b[1] + 1;
a[2] = b[2] + 1;

而不是

for(int i=0;i<3;++i) a[i] = b[i] + 1;

编译器是否仍可以对此代码进行矢量化?

此外,如果我使用替代引用访问元素,编译器是否有希望识别这两个是等价的? E.g。

int &x, &y, &z;
x = a[0]; y = a[1]; z = a[2];

然后用x,y和z替换a。

任何答案都非常感谢!提前谢谢。

1 个答案:

答案 0 :(得分:1)

所以我深入研究了三个简单案例生成的程序集。下面;

for(int i=0;i<3;++i) a[i] = 1.0; // case 1
a[0] = a[1] = a[2] = 1.0;        // case 2 
a.x = a.y = a.z = 1.0;           // case 3

为案例2和3生成的程序集是相同的。这很好,因为在第2种情况下,编译器给出了关于复制临时引用的“注释”(我的类重写了operator [])这意味着(纠正我,如果我错了)编译器正确使用返回值优化( RVO)。

然而,在第1种情况下,编译器输出了一个备注,它已经对循环进行了矢量化。组装也略有不同。具体来说它包含了这个额外的代码;

       .section .rodata, "a"
       .align 16
       .align 16
 _2il0floatpacket.1:
       .long   0x00000000,0x3ff00000,0x00000000,0x3ff00000
       .type   _2il0floatpacket.1,@object
       .size   _2il0floatpacket.1,16
 _2il0floatpacket.2:
       .long   0x00000000,0x3ff00000
       .type   _2il0floatpacket.2,@object
       .size   _2il0floatpacket.2,8

现在我从未使用过汇编,所以我不完全确定这些额外的东西是什么意思,但在我看来,暗示编译器在展开循环或通过引用访问的情况下无法进行向量化。在编译时缺乏对此效果的评论也暗示了这一点。

如果有人能证实这一点,那就太好了。