![]() |
1
33
现代硬件的一些事实,如x86或x86_64:
您可以阅读更多关于Agner Fogs中分支预测的内容优秀 manual. switch语句通常由编译器用跳转表替换。在大多数情况下,案件的顺序根本不会有什么不同。也有间接跳跃的预测机制。 所以问题不在于你的跳跃是否更有可能被执行,而是它们是否可以很好地预测,至少对于你打算运行代码的硬件来说。这个问题一点也不简单。但是,如果您有依赖于随机(或伪随机)条件的分支,您可以尝试在可能的情况下将其重新表述为无分支语句。 |
![]() |
2
7
您关于if语句的结论在我熟悉的大多数硬件上都不正确。问题不是你在跳,而是你在分支。根据比较的结果,代码可以有两种不同的方式。这会使大多数现代CPU上的管道停止运行。分支预测是常见的,并且大多数时候都会解决问题,但与您的示例无关。预测者同样能很好地预测一个比较是错误的,就像它能预测是正确的一样。 和往常一样,见维基百科: Branch Predictor |
![]() |
3
6
这要看情况而定。编译器将使用一系列与实现相关的内部标准来决定是否实现
不过,请记住,
|
![]() |
4
3
为了可读性,应以最有效的方式订购箱标签。 为了提高效率而重新排序案例标签是一种过早的优化,除非一个探查器明确告诉您这是一个问题。 |
![]() |
5
3
我认为即使是你最初的前提-你可以优化
在优化的构建中,我想您可能会惊讶于编译器有时为if语句生成什么。编译器可能会将一个或另一个(或两个)案例移动到某个不一致的地方。我认为,你试图通过玩“先到”的条件来幼稚地优化这一点,不一定会做你想做的。最好只有在检查编译器正在生成什么之后才能这样做。当然,这会成为一个昂贵的过程,因为即使在语句周围做一点点的更改,也会改变编译器决定生成输出代码的方式。
现在,就switch语句而言,我总是使用
如果您真的对充分利用该条件的性能感兴趣,可以考虑使用 MSVC's Profile Guided Optimization (pgo或“pogo”),它使用分析运行的结果来优化如何生成条件。我不知道GCC是否有类似的能力。 |
![]() |
6
2
我不确定C编译器,但我知道在汇编中,switch语句实际上可以被编程为跳转到特定行,而不是像if语句那样计算表达式。因为在select中,您拥有所有的常量,所以它只将case视为行号,而直接跳转到传入的行号(case值),而不进行任何计算。这使得案例陈述的顺序根本不重要。 |
![]() |
7
1
我假设你知道,只有当这是一个热点时,这才有关系。判断它是否是一个热点的最佳方法是运行代码,对程序计数器进行采样,并查看它是否在那里超过10%的时间。如果它是一个热点,请查看在执行
如果您不熟悉汇编语言,我建议您学习它,足够了解编译器生成的内容。这很有趣,也不难。 |
![]() |
8
0
正如其他人所说,这取决于很多事情,包括有多少情况,如何进行优化,以及您正在运行的体系结构。有关有趣的概述,请参见 http://ols.fedoraproject.org/GCC/Reprints-2008/sayle-reprint.pdf |
![]() |
9
-2
如果您将最常见的情况放在第一位,这将稍微优化代码,并且由于开关语句的工作方式,这也是正确的。当程序进入switch并发现一个正确的情况时,它将执行并点击break,这将退出循环。你的想法是正确的。 但是,我确实认为这种优化是非常小的,如果它减慢了开发时间,那么它可能不值得。另外,如果您必须彻底修改您的程序流以适应这一点,那么它可能不值得。你最多只能节省几个周期,而且可能永远也看不到改善。 |
![]() |
Community wiki · C中有哪些耗时的操作? 1 年前 |
![]() |
Community wiki · 将所有处理器电源都投入到任务中 1 年前 |
![]() |
Community wiki · C++为C添加了什么?[已关闭] 1 年前 |
![]() |
Community wiki · 打印1到1000,不带循环或条件 1 年前 |