使用展开循环进行矢量化

问题描述 投票:0回答:1

我正在使用 intel-cc 编译一些 C++ 代码,并且使用 -Wall 选项,它似乎对我的很多循环进行了矢量化。我目前的假设是这对性能有好处。

现在我的问题是这样的; if 我已经展开它而不是 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;

编译器还能向量化这段代码吗?

此外,如果我使用引用访问元素,编译器是否有希望认识到两者是等效的?例如

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

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

任何答案都非常感谢!预先感谢。

c++ vectorization icc
1个回答
2
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.