提问人:penguin2213 提问时间:9/15/2023 最后编辑:Peter Cordespenguin2213 更新时间:9/15/2023 访问量:152
在 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]
问:
在某些情况下(至少在逻辑上)如果我省略关键字就没有区别,例如:else
int func(int num)
{
if(num == 10) return 99999;
**else** return -1;
}
问题是,在比这更不重要的情况下,它的存在是否会在性能方面产生任何影响?我知道分支预测器和管道的存在,它是否受到 的缺席/存在的影响?也许这甚至无关紧要,因为编译器可能会优化它,但我很好奇。else
else
我一直在花时间在让你练习解决问题的网站上,几乎所有的问题都有微不足道的情况,例如,在制作 isPrime()
函数时,你可能想先过滤掉 <=1 个数字,然后才跳转到业务逻辑。这就是好奇心的来源。
答:
TL:DR:这可能没有区别,也没有容易预测的区别
CPU 运行机器代码,而不是 C++ 源代码。在机器代码中,我们只有“goto”(跳转)和条件分支。这对实际的程序逻辑没有影响,因此您期望任何一个版本都会编译为相同的机器代码。(如果没有,更糟糕的是错过了优化编译器缺陷。if()goto
else
但是源代码结构(例如将某些内容隐藏在主路径后面 vs. 后面 )可能会也可能不会影响编译器的启发式方法,以猜测更常采用的路径,从而将其布置为具有较少分支的快速路径,在没有 / 装饰器或配置文件引导的优化信息的情况下。编译器有各种启发式方法,用于猜测是否针对通常采用或通常不采用 an 的情况进行优化,例如查看条件以及它是将变量与小数还是大数进行比较,特别是如果它有任何关于被比较变量的值范围信息。else
if
[[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分钟指南!
评论
else
else
return -1