Goto优化重构

goto Optimization Refactor

本文关键字:重构 优化 Goto      更新时间:2023-10-16

我有一个" myfunction",如果我应该或不应该在上面使用goto,在类似的情况下(希望很少),我一直在痴迷。因此,我试图在这种情况下建立一个艰苦的习惯。待办事项或不做。

int MyFunction()
{   if (likely_condition)
    {
    condition_met:
        // ...
        return result;
    }
    else /*unlikely failure*/
    {   // meet condition
        goto condition_met;
    }
}

我打算为可能情况赢得有条件跳跃指令失败的好处。但是,我看不出编译器如何在没有类似的情况的情况下才能简化案例概率。

  1. 它可以正常工作吗?
  2. 好处值得混乱吗?
  3. 是否有更好的(更少的详细,更结构化,更富有表现力的)方法来实现此优化?

在我看来,您要做的优化大部分是过时的。大多数现代处理器都内置了分支机构的预测,因此(假设它使用足够注意)他们跟踪分支的频率,并预测分支是否可能基于其过去的被采取的模式。在这种情况下,速度主要取决于该预测的准确程度,而不是预测是否为进行。

因此,您最好使用更简单的代码:

int MyFunction() {   
    if (!likely_condition) {
        meet_condition();
    }
    // ...
    return result;
}

现代CPU如果对正确的分支预测进行正确的性能,则将其分支以同样的性能采用。因此,如果在内部循环中,if (unlikely) { meet condition } common code;的性能将与您所写的内容相匹配。

另外,如果您在两个分支中拼写了通用代码,则编译器将生成代码与您所写的相同:if子句和else条款将发出常见情况将jmp转到通用代码。您会一直以*out = whatever; return result;(例如CC_5)等简单的终端案例来看到这一点。调试时,很难说出您正在查看的return,因为它们都已合并。

  1. ,只要condition_met:不跳过变量初始化,代码看起来应该正如您期望的那样工作。

  2. 否,您甚至都不知道混淆版本将其编译成更最佳的代码。近期编译器优化(和处理器分支预测)变得非常聪明。

3。

int MyFunction()
{
    if (!likely_condition)
    {
        // meet condition
    }
    condition_met:
        // ...
    return result;
}

或,如果它有助于您的编译器(检查程序集)

int MyFunction()
{
    if (likely_condition); else
    {
        // meet condition
    }
    condition_met:
        // ...
    return result;
}

我强烈建议您在您的特定C 编译器(请参阅Portable Branch预测提示),而不是使用goto

int MyFunction()
{   if (__builtin_expect(likely_condition))
    {
        // ...
        return result;
    }
    else /*unlikely failure*/
    {   // meet condition
    }
}

正如其他人也提到的goto是骨头容易出错和邪恶的。