C++ goto优化重构
我有一个“我的功能”,我一直困扰着我是否应该或不应该在类似的情况下使用goto。因此,我正在努力为这种情况建立一个刻苦的习惯。做还是不做C++ goto优化重构,c++,c,goto,C++,C,Goto,我有一个“我的功能”,我一直困扰着我是否应该或不应该在类似的情况下使用goto。因此,我正在努力为这种情况建立一个刻苦的习惯。做还是不做 int MyFunction() { if (likely_condition) { condition_met: // ... return result; } else /*unlikely failure*/ { // meet condition goto
int MyFunction()
{ if (likely_condition)
{
condition_met:
// ...
return result;
}
else /*unlikely failure*/
{ // meet condition
goto condition_met;
}
}
我打算在可能的情况下获得失败的条件跳转指令的好处。然而,我不明白如果没有这样的东西,编译器如何知道应该简化哪些用例概率
条件满足:
不跳过变量初始化,代码就应该像您期望的那样工作如果做出正确的分支预测,现代CPU将以相同的性能执行该分支。因此,如果这是在一个内部循环中,
if(不太可能){meet condition}公共代码的性能代码>将与您编写的内容匹配
此外,如果您在两个分支中拼写出公共代码,编译器将生成与您编写的代码相同的代码:公共大小写将针对if
子句发出,而else
子句将针对公共代码发出jmp
。您一直可以在较简单的终端案例中看到这一点,如*out=whatever;返回结果代码>。调试时,可能很难判断您正在查看哪个返回,因为它们都已合并。在我看来,您尝试进行的优化大多已过时。大多数现代处理器都内置了分支预测,因此(假设它的使用足以引起注意)它们跟踪分支被执行的频率,并根据分支被执行与否的过去模式预测分支是否可能被执行。在这种情况下,速度主要取决于预测的准确度,而不是预测是用于预测还是不用于预测
因此,您最好使用更简单的代码:
int MyFunction() {
if (!likely_condition) {
meet_condition();
}
// ...
return result;
}
<>我强烈建议使用C++代码> <代码> >代码>宏(GCC)或类似的代码,而不是使用<代码> Goto >:
int MyFunction()
{ if (__builtin_expect(likely_condition))
{
// ...
return result;
}
else /*unlikely failure*/
{ // meet condition
}
}
正如其他人也提到的那样,goto
容易出错,而且从本质上讲是邪恶的。为什么不能将其重构为return conditionMet();在这两种情况下?我假设您的结果是以某种方式计算出来的,那么为什么不将其放入函数中呢?请不要使用goto
!您是否真的知道这种优化在代码的真正瓶颈中起到了可测量的帮助?如果不是的话,问题2的答案很明显,这使得你剩下的问题无关紧要。强制性@EtiennedeMartel和任何人:我的部分努力是减少冗余,所以这解释了很多。我减少返回点的错误版本。请注意,分支预测是否生效取决于分支被命中的频率,并且在某些体系结构中存在固定的偏差(默认情况下,英特尔偏向于“if”端)。您可以使用intrinsic提示编译器,分支可能不太可能克服这种偏差(编译器将执行平台要求的任何操作,包括重新排序代码,如果这可能会产生更好的性能)。最后,编写可维护的代码,如果您的评测显示确实存在瓶颈,则只需担心性能和微优化。
int MyFunction() {
if (!likely_condition) {
meet_condition();
}
// ...
return result;
}
int MyFunction()
{ if (__builtin_expect(likely_condition))
{
// ...
return result;
}
else /*unlikely failure*/
{ // meet condition
}
}