可以重复调用相同的函数提供更好的性能吗?

时间:2013-08-05 14:02:22

标签: c

我的代码如下:

void foo(unsigned long k)
{
    if (k & 1)
    {
        bar(k/2 + 1);
        bar(k/2);
        bar(k/2 + 1);
    }
    else
    {
        bar(k/2);
        bar(k/2);
        bar(k/2);
    }
}

void bar(unsigned long k)
{
  switch(k)
  {
     case default: special_default(); break;
     case 1: specialbar1(); break;
     case 2: specialbar2(); break;
     <more cases>
     case 16: specialbar16(); break;
  }
}

当为foo的偶数值调用k时,性能会好得多。每个specialbar#()方法都使用多个堆栈变量,随着k的增加,这些变量的数量急剧增加。要明确specialbar#()使用约3 * k个局部变量,所有这些变量都是unsigned long long变量。

例如foo(32)的执行速度比foo(31)快约15%。我正在使用Visual Studio 2012,性能分析向我保证,对specialbar16的两次调用和对specialbar15的一次调用比对specialbar16的三次连续调用要多得多。

k是偶数时,编译器是否可以利用连续三次调用?也就是说,它是否可以实现在偶数k的三次连续调用中堆栈基本相同但奇数k无法进行相同的优化?

2 个答案:

答案 0 :(得分:2)

  

当k为偶数时,编译器是否可以利用三次连续调用?那就是它可以意识到堆栈在连续三次连续调用中基本相同,但奇数k不可能进行相同的优化吗?

这似乎不值得回答,但是,是的,这完全有可能。编译器可以识别每次调用需要相同的堆栈布局,因为它每次都是相同的方法,因此避免了每个方法调用的整个堆栈设置/拆除。在这种情况下,可能还会内联方法调用 - 代码在调用者中生成。

最有可能对其他情况执行类似的优化,尽管优化很棘手,并且有时会有一些细微的原因导致编译器无法执行它。

答案 1 :(得分:1)

当k为奇数(k / 2 + 1)+ 1时,你的foo函数会执行额外的逻辑。

要回答您的具体问题,可以重复通话以提高效果。是的,当参数相同时,函数中的各个部分是相同的,这样可以使“分支预测”最佳地工作。