如何让GCC在-Os优化级别下遵循__builtin_expect提示进行分支布局,使预期分支为fallthrough case?
如何让GCC在-Os优化级别下遵循__builtin_expect提示进行分支布局,使预期分支为fallthrough case?
嗨,这个问题我刚好踩过坑,来给你详细捋一捋~
你遇到的核心矛盾是:-Os的核心目标是把代码体积压到最小,GCC默认会优先选最紧凑的分支指令实现,这就可能直接忽略__builtin_expect给的分支预测提示,没把你标记的“大概率会走的分支”设成不需要跳转的fallthrough(直通)分支。
要解决这个问题,给你两个实用的编译选项方案:
首选方案:禁用短分支优化
给GCC加上编译选项-fno-short-branches。这个选项会让编译器不再为了追求最短跳转指令而牺牲分支布局的合理性,转而尊重__builtin_expect的提示,把你标记的预期分支设为fallthrough的直通分支,同时依然会尽量控制代码体积,完全贴合-Os的优化核心。拿你给出的示例代码来说:
#include <stdio.h> #define TRAPASSERT(X) do{if(__builtin_expect(!(X),0)){__builtin_trap();}}while(0) void example(unsigned X){ TRAPASSERT(X < 32); printf("%u\n", X); }用
-Os -fno-short-branches编译后,GCC就会把X < 32为真的预期分支设成直通分支,只有断言失败的小概率分支才会触发跳转,完美符合你用__builtin_expect(!(X),0)表达的意图。可选补充:跳转指令对齐
如果还想进一步提升分支预测的效率,可以额外加上-falign-jumps=16(对齐值可以根据目标架构调整,比如16、32)。这个选项会让跳转目标地址对齐到指定的字节边界,让CPU的分支预测器工作更顺畅,代价只是极少量的代码体积增加,在-Os下基本是可接受的。
另外要提一句,不同GCC版本对这些选项的支持可能有细微差别,建议你结合自己用的GCC版本做个小测试,确保效果符合预期。
备注:内容来源于stack exchange,提问作者Petr Skocik
相关产品推荐
相关产品推荐

