例如,在这段代码中:
if(x) {
printf("A\n");
}
else {
printf("B\n");
}
字符串
编译器组织输出,以便当“x”为真时,分支“不被采用”,并且A执行。我尝试添加likely
和unlikely
,结果总是这样:then
语句总是对应于not taken
。
所以我的问题是:这是否总是保证如此?
我对likely
的理解是,它应该给予编译器关于如何布局的提示,所以在这种情况下它被忽略了,因为它没有改变块的布局,我想知道是否有任何语言保证,或者编译器决定忽略这个建议(或者只是还没有实现它)。
1条答案
按热度按时间xmakbtuz1#
在语言标准中根本没有任何东西说明如何在编译的机器指令中布局分支。在as-if规则下,编译器可以以任何方式编译程序,使得可观察的行为与抽象机器上允许的行为相匹配。在机器指令中如何布局分支并不影响可观察的行为。
[[likely]]
和[[unlikely]]
属性只是对编译器的提示,即标记的路径比执行流中的其他路径更可能或更不可能。由编译器来决定如何或是否使用这些信息。因此,如果编译器没有以最高性能的方式布局分支,那么这至多是编译器的实现质量问题,假设您启用了优化,并且您使用
[[likely]]
或[[unlikely]]
提供了必要的信息。但也许编译器实际上考虑了这些信息,但有一些其他原因仍然做了一个与您预期不同的布局,例如。因为其它原因可能比跳转指令更有效。在做出假设之前仔细分析您的特定测试用例,如果有遗漏的优化,请提交错误报告。此外,请确保编译器设置为C20或更高版本的模式,或者也支持以前标准版本中的属性。它们只在C20中引入,不受支持的属性应该被忽略。在这种情况下,编译器可能会发出警告,也可能不会发出警告。