提问人:Luchian Grigore 提问时间:7/9/2012 最后编辑:Luchian Grigore 更新时间:7/9/2012 访问量:227
为什么将返回移动到函数的末尾效率较低?[关闭]
Why is moving return to the end of the function less efficient? [closed]
问:
编辑:删除UB后(好地方,我错过了),时间或多或少相同。将标记版主以将其删除。
这两个函数是相同的,除了在两个分支上都有返回值,而末尾有一个:foo
if
goo
return
int foo()
{
static int x = 0;
if ( x )
{
x > 2 ? x = 0 : ++x;
return x-1;
}
else
{
x++;
return x-1;
}
}
int goo()
{
static int x = 0;
if ( x )
{
x > 2 ? x = 0 : ++x;
}
else
{
x++;
}
return x-1;
}
这些数字就在那里,所以优化不会太难,函数调用也不会被优化。在 MSVS 2010 上进行了全面优化。
调用函数 4000000000 次,采样 10 次,总是更快:foo
foo
- 平均 8830 毫秒goo
- 平均 8703 毫秒
差异很小,但它就在那里。为什么?另外,为什么编译器不将它们优化为相同的内容?
答:
3赞
Torsten Robitzki
7/9/2012
#1
看一下汇编器的输出,在 goo() 的第一个分支中可能会跳转到函数的末尾。
评论
0赞
TerryE
7/9/2012
是的,但第一个分支从未被占用。
1赞
Chris Dargis
7/9/2012
我认为这与分支预测和流水线有关。
1赞
Torsten Robitzki
7/9/2012
@TerryE x 是静态的,因此它在第二个早午餐中递增,因此在下一个函数调用中调用第一个分支。
0赞
TerryE
7/9/2012
@TorstenRobitzki,是的,我也意识到在发表评论后,但为时已晚,无法编辑它:哎呀: -- Mindfart
0赞
Dorin Rusu
7/9/2012
#2
我假设这是因为在操作完成的那一刻,每个 ,都会返回计算出的变量。if
foo
goo
,即使以为它做了同样的事情,除了两次返回之外,还是要检查语句。这需要一些时间(非常小),但正如你所看到的,它是可测量的。else
评论
4赞
Luchian Grigore
7/9/2012
你的意思是它仍然必须检查声明?else
0赞
Brandon
12/31/2013
我认为其他的不需要检查。首先,没有“检查”另一个。如果之前的一切都是假的,否则就是真的。此外,如果条件为真,则该块永远不会运行,因此我看不出工作有任何差异。就像其他人说的,汇编代码可能不同。if
else
-3赞
Narendra
7/9/2012
#3
如果是 foo,则不会执行“if”和“else”的尾括号。退货后
语句 控件将直接获得函数的尾括号。
这就是为什么 foo 需要更少的时间。
评论
1赞
TerryE
7/9/2012
Naren,核心不执行“大括号”。它执行指令。但是,您在某种程度上是对的,因为某些编译器在 4/8 字节边界上对齐分支目标以帮助改进指令缓存,并且为第一个目标提供额外的目标和额外的代码可能会影响时序。return x+1
0赞
Narendra
7/9/2012
我知道这没有执行,但我通过给出断点来尝试这样做,执行直接转到函数的结束大括号......您还可以尝试使用断点并检查。
评论
++x
x = x > 2 ? 0 : ++x