编译期优化
1. likely & unlikely 通过代码中设置先验概率提升分支预测概率
- 其底层核心是通过增加分支预测的准确度来增加流水线技术的使用,从而增加执行的吞吐量。
- C++20后,unlikely 和likely作为了关键字; 优化写法是
[[likely]]
&[[unlikely]]
#include <iostream>
using namespace std;
int function(int type) {
int ret = 0;
switch(type) {
// 告诉编译器,更多情况下是type=0的情况。
[[likely]] case 0:
break;
[[unlikely]] case 1:
ret = 1;
break;
}
return ret;
}
if (ptr == nullptr) [[likely]] {
return;
}
// 注意一种不正确的写法:
[[likely]] if (whatever) {
} means something else entirely.
- it means that the if statement itself is "likely", not a branch of it.
- C++20之前,可以通过自己定义宏来实现,但是需要gcc编译器版本
GNUC > 3
- 不能在switch中使用。
// 定义
#if __GNUC__ >= 3
#define cyber_likely(x) (__builtin_expect((x), 1))
#define cyber_unlikely(x) (__builtin_expect((x), 0))
#else
#define cyber_likely(x) (x)
#define cyber_unlikely(x) (x)
#endif
// 在条件语句中使用
if (cyber_unlikely(object == nullptr)) {
return;
}
// while判断也可以使用
while (cyber_unlikely(!shut_down_.load())) {
scheduler::Instance()->CheckSchedStatus();
std::unique_lock<std::mutex> lk(lk_);
cv_.wait_for(lk, std::chrono::milliseconds(sysmo_interval_ms_));
}
参考源码:https://github.com/ApolloAuto/apollo/blob/master/cyber/base/macros.h
运行期优化
// 如果是下面的if语句,为了减少分支效率的影响,可以用if + return,不要else。
if (something) {
// doing
return ret;
} else {
return ret; // or only log something.
}
// 更好的写法
if (!something) {
return ret; // or only log something
}
// doing
return ret;
reference
- https://www.cnblogs.com/qiangz/p/17088276.html : 该博客讲解了添加unlikely或者不添加时,编译出来的汇编语言的区别,从而能容易理解该属性的作用。