【发布时间】:2021-01-24 22:27:51
【问题描述】:
我遇到过一些场景,我想说一个函数的返回值很可能在函数体中,而不是调用它的 if 语句。
例如,假设我想将代码从使用 LIKELY 宏移植到使用新的 [[likely]] 注释。但这些在语法上不同的地方:
#define LIKELY(...) __builtin_expect(!!(__VA_ARGS__),0)
if(LIKELY(x)) { ... }
对
if(x) [[likely]] { ... }
没有简单的方法可以重新定义 LIKELY 宏以使用注释。会定义一个类似的函数
inline bool likely(bool x) {
if(x) [[likely]] return true;
else return false;
}
将提示传播到 if?喜欢在
if(likely(x)) { ... }
同样,在通用代码中,在实际的if 语句中直接表达算法似然性信息可能很困难,即使该信息在其他地方是已知的。例如,copy_if 谓词几乎总是为假。据我所知,没有办法用属性来表达,但是如果分支权重信息可以通过函数传播,这是一个已解决的问题。
到目前为止,我还没有找到有关此的文档,并且我不知道通过查看输出的程序集来测试它的良好设置。
【问题讨论】:
-
这可以完成似乎是合乎逻辑的。那么问题是任何给定的编译器是否真的足够聪明来做到这一点。你有什么特别的编译器吗?当然,就标准而言,没有编译器有义务对提示做任何事情。
-
@NateEldredge 就我个人而言,我对 clang 和 gcc 最感兴趣,但了解更多永远不会受到伤害。
-
编译器在内联后跟踪某物的“预期”值当然是合理的。特别是 GCC,因为原始
__builtin的语义是为变量提供预期值,而不是特定于在分支中使用它。 (正如 Nate 所示,GCC 会这样做,但会发出叮当声主干 seems not to) -
事后看来,当然,最好将宏最初定义为
#define LIKELY(x) (__builtin_expect(!!(x),0))并将其用作if LIKELY(x) { ... }。这样,移植就很容易了。 (或者甚至可以定义一个if_likely(x)宏,并将if关键字移到宏定义中。)
标签: c++ compiler-optimization c++20 branch-prediction