问题1:调用函数的执行时间



如果下面函数foo((的大多数调用都传递了10个特定值中的一个,那么哪种方法会显著减少调用函数的执行时间?

哪些选择是正确的?我认为选择D,但我不确定。专家。想法?

A。将*替换为针对10个值的if-else块测试,并相应地分配r
B。删除内联
C。删除foo((并将耗时的操作移到其调用者
D。将*替换为执行表查找的代码,其中包含r
E的10个值和相应值。将*替换为swtich?

1 inline int foo (int x) {
2   int r;
3 
4   * // time-consuming operation on x, result stored in r
5 
6   return r;    
7 }

B不会有任何影响。CCD_ 1仅抑制一个定义规则;它不会强制编译器内联函数。

C不太可能产生任何影响;如果编译器确定该函数是一个很好的内联候选者,它就会这样做。手动内联它可能会使性能恶化

其他三个选项(A、D和E(的性能可能都比其他选项更好或更差,这取决于许多因素。这一切中最大的因素是编译器。现代编译器非常擅长优化。A、 D和E都可以被琐碎地转换成彼此。因此,它们可能都和彼此一样快。

因此,答案在很大程度上取决于特定的编译器(以及该编译器的版本(以及所使用的编译标志。给定一个特定的编译器,我需要对每个选项进行适当的基准测试,并一直进行优化,以确定正确的答案。

如果我参加这个测试,我会拒绝回答这个问题,并给监考者/作者发一张纸条,表明这个问题有缺陷。


现在我已经解决了这个问题,如果我们假设所有编译器优化都被禁用,D可能是最快的,因为它是无分支的。A和E都涉及分支,并且失败的分支预测代价高昂。

我希望D是最快的。A和E的表现应该大致相同。


在我使用-O3对gcc进行的测试中,E被优化为查找表(如D(,但a仍然是一系列条件跳跃。所以在这个特殊的测试中,D和E都是正确的答案。

切换到使用-O3的clang,它优化了A和E以使用查找表(如D(。它为所有选项生成等效的程序集。

相关内容

  • 没有找到相关文章