一尘不染

Linux内核中可能的/不太可能的宏如何工作,它们的好处是什么?

linux

我一直在研究Linux内核的某些部分,并找到了如下调用:

if (unlikely(fd < 0))
{
    /* Do something */
}

要么

if (likely(!err))
{
    /* Do something */
}

我找到了它们的定义:

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)

我知道它们是为了优化,但是它们如何工作?使用它们可以预期多少性能/尺寸下降?至少在瓶颈代码中(当然在用户空间中)值得麻烦(并且可能会失去可移植性)。


阅读 302

收藏
2020-06-02

共1个答案

一尘不染

它们提示编译器发出指令,这些指令将导致分支预测偏向跳转指令的“可能”一侧。如果预测正确,这将是一个巨大的胜利,这意味着跳转指令基本上是免费的,将花费零个周期。另一方面,如果预测错误,则意味着需要清除处理器管道,这可能会花费多个周期。只要预测在大多数时间都是正确的,这将对性能有好处。

像所有这样的性能优化一样,您应该只在进行广泛的性能分析后才能执行此操作,以确保代码确实处于瓶颈,并且可能考虑到微观性质,因此代码正在紧密循环中运行。通常,Linux开发人员都非常有经验,所以我想他们会做到的。他们并不十分在意可移植性,因为它们只针对gcc,并且对要生成的程序集有着非常密切的了解。

2020-06-02