icc没有执行循环不变代码运动

时间:2013-10-19 13:57:56

标签: c++ c for-loop compiler-optimization icc

有人可以解释为什么icc没有在下面的代码1中进行循环不变的代码运动(移动指针的a)。当指针赋值从代码2中的t6循环中移出时,我看到性能提高了40%。我尝试将指针'a'标记为const并限制,让编译器知道指针'a'不会在t6循环内改变。我正在使用icc中的-ansi-alias选项编译代码。

// code 1

          for (t4=256*t1; t4<=256*t1+254; t4++) {
            lbv=256*t2;
            ubv=256*t2+255;
            for (t6=lbv; t6<=ubv; t6++) { 
                double *restrict const a = a_trans[lbv /256]; //loop invariant code
                a[t6-lbv]=a[t6-lbv]/a[t6-lbv];
            }
          }

//代码2

       for (t4=256*t1; t4<=256*t1+254; t4++) {
            lbv=256*t2;
            ubv=256*t2+255;
            double *restrict const a = a_trans[lbv /256];
            for (t6=lbv; t6<=ubv; t6++) {
                a[t6-lbv]=a[t6-lbv]/a[t6-lbv];
            }
       }

此代码由源到源转换器生成。手动操作非常繁琐 将此转换应用于大量循环。有没有办法让icc自动进行这种转换?

1 个答案:

答案 0 :(得分:1)

似乎a_translbv都在外部作用域中定义,而不是常量。你不能指望icc足够聪明,理解a不会改变。对于像a_translbv这样的大范围变量,编译器会将它们分配到RAM中。循环期间它们可能会被更改。实际上,如果它们被定义为局部变量(在寄存器中分配),则编译器可能能够对其进行优化。

      for (t4=256*t1; t4<=256*t1+254; t4++) {
        lbv=256*t2;
        ubv=256*t2+255;
        const int local_lbv=lbv;
        const double** local_a_trans=a_trans;
        for (t6=lbv; t6<=ubv; t6++) { 
            double *restrict const a = local_a_trans[local_lbv /256];
            a[t6-lbv]=a[t6-lbv]/a[t6-lbv];
        }
      }

通常,编译器旨在编译和优化由人类编写的代码,而不是源代码翻译器。

另一方面,您可以尝试使用-O3-ipo进行更积极的代码优化

修改

尝试本地化变量后,仍然没有性能提升。我认为我们可以得出结论,代码生成器不会生成具有足够高性能的代码。自动生成后,建议手动重写。