c++ - [[likely]] 和 [[unlikely]] 的效果可以传递/推断吗?
问题描述
C++20 引入了属性[[likely]]
和[[unlikely]]
用于可能执行或不太可能执行的信号语句以帮助优化。__likely
从历史上看,这些属性是特定于编译器的,并且隐藏在__unlikely
宏函数后面以帮助优化分支语句;然而,C++20 更进一步,允许它们出现在任何语句中。
从理论上讲,这应该允许基于上下文和可见性进行[[likely]]
推断[[unlikely]]
——例如:
// Just an opaque function to call so we see it in the generated assembly
void something_expensive();
// Something we know to always be unlikely
[[gnu::always_inline]]
inline void unlikely_code_path() {
[[unlikely]] something_expensive();
}
void test_unlikely(bool x) {
if (x) /* [[unlikely]] inferred? */ { unlikely_code_path(); }
}
我在这个例子中使用了inline
d/visible 函数调用,因为我可以看到assert
这对于像为了。但是,我没有看到任何编译器实际上利用了这一点。
GCC 和 Clang 都生成相同的汇编输出,它们都没有利用[[unlikely]]
(或[[likely]]
)知识:
test_unlikely(bool):
test dil, dil
je .L4
jmp something_expensive()
.L4:
ret
我的期望是,它test_unlikely
会知道[[unlikely]]
分支并生成类似于 if this are 生成的内容if (b) [[unlikely]] { ...}
,即:
test_unlikely(bool):
test dil, dil
jne .L6
ret
.L6:
jmp something_expensive()
编译器是否错过了标记“热门”和可能路径的机会?或者我是否缺少关于 C++ 语言的一些东西,实际上可能会阻止这种优化在实践中单独使用属性来实现?
(注意:我知道 C++ 中的属性实际上是非绑定契约,因此编译器不需要尊重它们;但这里的编译器显然尊重某些情况,这让我认为这只是一个错过的优化)
解决方案
推荐阅读
- apache-flink - Apache Flink:IDE 执行中的作业恢复未按预期工作
- reactjs - 使用 Devextreme React Scheduler 动态改变调度(react)
- python - 如何在 Tkinter 中滚动浏览一组标签小部件?
- python - 如何在 Windows 版 Git Bash 中启用 Python 上次命令历史记录?
- autohotkey - 我需要一个热键,例如“c”来启用脚本
- javascript - Camera js Web App无法获取相机供稿
- powershell - 将日历添加到组合框
- git - 如何获取 tfs 中两个变更集或 git 中两个分支的多个文件的所有更改?
- video - 视频点播如何在 Youtube 中工作?
- gcc - 为什么独立的 C hello 程序在用作动态链接器时会崩溃