Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ goto优化重构_C++_C_Goto - Fatal编程技术网

C++ 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

我有一个“我的功能”,我一直困扰着我是否应该或不应该在类似的情况下使用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
        }
    }