在 c++ 中,在不改变程序流程的情况下,使用“else”对性能的重要性是什么?[复制]

In c++ what is the importance in terms of performance of using 'else' in situations where it doesn't change the flow of the program? [duplicate]

提问人:penguin2213 提问时间:9/15/2023 最后编辑:Peter Cordespenguin2213 更新时间:9/15/2023 访问量:152

问:

在某些情况下(至少在逻辑上)如果我省略关键字就没有区别,例如:else

int func(int num)
{
    if(num == 10) return 99999;
    **else** return -1;
}

问题是,在比这更不重要的情况下,它的存在是否会在性能方面产生任何影响?我知道分支预测器和管道的存在,它是否受到 的缺席/存在的影响?也许这甚至无关紧要,因为编译器可能会优化它,但我很好奇。elseelse

我一直在花时间在让你练习解决问题的网站上,几乎所有的问题都有微不足道的情况,例如,在制作 isPrime() 函数时,你可能想先过滤掉 <=1 个数字,然后才跳转到业务逻辑。这就是好奇心的来源。

C++ IF语句 优化 预测

评论

1赞 Eljay 9/15/2023
查看生成的程序集。生成的代码可能是相同的。对于最后一种情况,我省略了,但这只是我个人的惯例。就语言而言,它是六种语言,另一种语言六种。else
5赞 user229044 9/15/2023
处理器上没有指令。如果你真的担心会有某种性能差异,你必须尝试并衡量。实际上,你必须谈论一段特定的代码,而不是任意的“不那么微不足道”的情况。else
0赞 Pepijn Kramer 9/15/2023
此外,如果您担心性能,您可以给出一个提示,如果不太可能是真的:en.cppreference.com/w/cpp/language/attributes/likely......但唯一真正的证据仍然是测量(分析)你的代码并修复真正的瓶颈。
0赞 Pepijn Kramer 9/15/2023
关于让你解决实际问题的网站,你并不意味着竞争编码的权利。因为不要费心在这里和那里寻找几纳秒......这远低于他们的测量精度(至少几十毫秒)。真正的目标只是把复杂(大O)做好。哦,它似乎也发现了真正糟糕的编码实践
0赞 BoP 9/15/2023
这与性能无关,而是与可读性有关。使用带有两个返回值的 if-else 可以让读者清楚地知道正好有两个选项。否则,您可以有几个单独的 if,其中包含各种条件的回报,然后是“其余”的回报。return -1

答:

2赞 Peter Cordes 9/15/2023 #1

TL:DR:这可能没有区别,也没有容易预测的区别

CPU 运行机器代码,而不是 C++ 源代码。在机器代码中,我们只有“goto”(跳转)和条件分支。这对实际的程序逻辑没有影响,因此您期望任何一个版本都会编译为相同的机器代码。(如果没有,更糟糕的是错过了优化编译器缺陷。if()gotoelse

但是源代码结构(例如将某些内容隐藏在主路径后面 vs. 后面 )可能会也可能不会影响编译器的启发式方法,以猜测更常采用的路径,从而将其布置为具有较少分支的快速路径,在没有 / 装饰器或配置文件引导的优化信息的情况下。编译器有各种启发式方法,用于猜测是否针对通常采用或通常不采用 an 的情况进行优化,例如查看条件以及它是将变量与小数还是大数进行比较,特别是如果它有任何关于被比较变量的值范围信息。elseif[[likely]][[unlikely]]if

请参阅 Ciro 的回答,其中显示了对分支布局的影响。请注意,这与运行时分支预测无关,除非在较旧的 CPU 上,当动态预测器处于冷状态时,有时会使用静态预测(正向/向后不进行)。使用 IT-TAGE 预测器(至少在 Haswell 之后的英特尔中),这种情况不会发生,它们总是可以预测一些事情。在机器代码中获取分支的效率比下降(例如进入主体)要低一些,因为前端不仅仅是获取连续的代码。if

但是,源代码布局和机器代码布局之间没有直接或简单的联系;这是编译器的工作,优化分支布局,而不仅仅是将 C 音译为 asm,所以如果你想知道编译器做了什么,你将不得不查看 asm(例如在 https://godbolt.org/ 上)。参见 如何消除 GCC/clang 组件输出中的“噪音”?

如果您对微优化感兴趣,请参阅预测现代超标量处理器操作的延迟需要注意哪些因素以及如何手动计算延迟? 并阅读最近 CPU 的细节,比如 Chips & Cheese 对 Zen 4 的文章。https://chipsandcheese.com/2022/11/05/amds-zen-4-part-1-frontend-and-execution-engine/还有像大卫·坎特(David Kanter)对桑迪布里奇(Sandybridge)和哈斯韦尔(Haswell)的深入研究这样的旧文章。还链接了 https://stackoverflow.com/tags/x86/info,例如 Agner Fog 的优秀微架构指南:https://www.agner.org/optimize/

有关基础知识,请参阅现代微处理器 90分钟指南!