C ++嵌套循环不变代码运动

时间:2017-07-24 21:30:16

标签: c++ gcc optimization

我想知道在哪些条件下可以优化嵌套循环的不变部分。

为此,我编写了两个函数,其中一个函数实现了三个嵌套循环的分解,而另一个函数没有。

非分解函数如下:

svg.objectCaching = true;
svg.globalCompositeOperation = 'source-atop';

const cols = ["red","green","blue","yellow","black","orange"];
var colCount = 0;
setInterval(()=>{
  svg.paths.forEach(p=>{ p.fill = cols[colCount % cols.length] })
  colCount += 1;
  svg.dirty = true;
  canvas.renderAll();
},500)

虽然分解函数是:

template<int k>
double __attribute__ ((noinline)) evaluate(const double u[], const double phi[])
{
  double f = 0.;
  for (int i3 = 0;i3<k;++i3)
    for (int i2 = 0;i2<k;++i2)
      for (int i1 = 0;i1<k;++i1)
        f += u[i1+k*(i2+k*i3)] * phi[i1] * phi[i2] * phi[i3];
  return f;
}

我打电话给以下主要内容:

template<int k>
double __attribute__ ((noinline)) evaluate_fact(const double u[], const double phi[])
{
  double f3 = 0.;
  for (int i3 = 0;i3<k;++i3)
    {
      double f2 = 0.;
      for (int i2 = 0;i2<k;++i2)
        {
          double f1 = 0.;
          for (int i1 = 0;i1<k;++i1)
            {
              f1 += u[i1+k*(i2+k*i3)] * phi[i1];
            }
          f2 += f1  * phi[i2];
        }
      f3 += f2 * phi[i3];
    }
  return f3;
}

对于小k,两个函数都生成相同的汇编代码,但在某个大小k~ = 10之后,程序集看起来不再相同,并且callgrind显示在非因子化版本中执行的操作更多。

我应该如何编写代码(如果可能的话),或者我应该告诉GCC如何将evaluate()优化为evaluate_fact()???

我正在使用GCC 7.1.0。 with flags -Ofast -fmove-loop-invariants

使用-funroll-loops没有帮助,除非我添加--param max-fully -pened-insns = 10000 --param max-fully-peel-times = 10000但这是一个完全不同的东西,因为它基本上是展开一切,装配很广泛。

使用-fassociative-math也无济于事。

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/kernel_tests/parsing_ops_test.py#L954声称:“传统的循环不变代码运动,通常由通用编译器应用,仅检查最内层循环的不变性。”这适用于我的代码吗?

谢谢!

0 个答案:

没有答案