TwKit
正在载入
TwKit

同一段 switch,编译后可能是跳转表、比较树,也可能用位测试。 一份 2024 年的 GCC 源码分析(示例主要用 -O3)展示了几种处理方式: • 值… · @BaiBtw · TwKit

@BaiBtw

同一段 switch,编译后可能是跳转表、比较树,也可能用位测试。 一份 2024 年的 GCC 源码分析(示例主要用 -O3)展示了几种处理方式: • 值密集、目标不同:可生成跳转表。case 为 97~101 时,先减去 97,再检查范围并按索引跳转。 • 值稀疏:可能改成比较树,不必按源码顺序逐个判断。连续的 42~45 若通向同一代码块,还能合成范围判断。 • 小范围内多个值通向少数目标:可压成位集。例如字符 '0'、'2'、'4'、'5'、'7'、'9'、'A'、'C'、'E' 的 ASCII 值减去 48 后,对应掩码 2753205;先检查范围,再测试对应位。 策略还能混用:case 1~5 用跳转表,离群的 100 单独比较,不需要为整段 1~100 都铺表。 文中实现先寻找位集簇,再对剩余部分寻找跳转表簇,最后组织比较树;位集和跳转表也可以成为树的叶子。这是编译时的选择过程,不是每次运行都依次走三套逻辑。 选择依据也不只是 case 数量:值域、合并后需要多少次比较、不同出口数、分支概率都会影响结果。位集受寄存器宽度和收益判断约束;跳转表有边界检查与间接跳转开销,小表未必合算。 这些是特定时期实现中的启发式规则,目标架构、优化选项和编译器版本都会影响结果,不能把某个密度阈值当成通用定律。

曝光 184 · 评论 3 · 点赞 3 · 书签 1

查看原帖