【问题标题】:icc is not performing loop invariant code motionicc 没有执行循环不变的代码运动
【发布时间】:2013-10-19 13:57:55
【问题描述】:

有人可以解释为什么 icc 在下面的代码 1 中没有执行循环不变代码运动(a 的移动指针分配)的原因。当 a 指针分配移出 t6 循环时,如代码 2 中所做的那样,我看到性能提高了 40%。我尝试将指针“a”标记为 const 和限制,让编译器知道指针“a”不会在 t6 循环内更改。我正在 icc 中使用 -ansi-alias 选项编译代码。

//代码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 自动进行这种转换?

【问题讨论】:

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


    【解决方案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 进行更积极的代码优化

    编辑

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

    【讨论】:

    • 如果你能做到,为什么不把那条线移出循环呢?
    • 即使您将 'lbv' 作为局部变量并在函数中将 'a_trans' 标记为 const/restrict,问题仍然存在。我在 icc 中使用了“-03”和“-ipo”选项。是否有任何其他关键字可以让 icc 知道“a_trans”不会被循环更改?
    • 正如我之前提到的,这段代码是由源到源的翻译器生成的,我可以轻松地更改最里面的 for 循环体中的文本,但不能在 for 循环之间添加文本。 'lbv' 在生成的代码中已经是本地的。
    • 尝试使它们既是本地的又是常量。如果您依赖源代码翻译器,您可能会期望很高。
    • 我尝试通过添加 'double** local_a_trans=a_trans;' 将 a_trans 设为本地在 t4 循环本身之前,仍然没有获得性能
    猜你喜欢
    • 2016-05-25
    • 2020-07-05
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多