2

我阅读了linux内核文档,这个文件描述了静态密钥: http: //lxr.linux.no/linux+v3.11.1/Documentation/static-keys.txt

那么,static-key 和 __builtin_expect 有什么区别呢?它们都暗示我们可以使用它们来实现likyly()和similarly( )

4

1 回答 1

7
  • __builtin_expect在需要由 CPU 评估的代码中引入了真正的测试和分支指令,而来自更可能要遵循的路径的指令继续被预取到 CPU 管道中。

  • static_key_*引入了一条NOP指令,该指令在代码中占据足够的空间,以后可以在运行时修补以添加jmp <label>. 这可用于适应对常规工作情况零影响的调试打印,即在未调试代码时。

Linux 内核文档中static-keys

gcc (v4.5) 添加了一个新的“asm goto”语句,允许分支到标签:
gcc.gnu.org/ml/gcc-patches/2009-07/msg01556.html

使用“asm goto”,我们可以创建默认采用或不采用的分支,而无需检查内存。然后,在运行时,我们可以修补分支站点以更改分支方向。

例如,如果我们有一个默认禁用的简单分支:

if (static_key_false(&key))
        printk("I am the true branch\n");

因此,默认情况下不会发出“printk”。生成的代码将包含一条直线代码路径中的单个原子“无操作”指令(x86 上为 5 个字节)。当分支被“翻转”时,我们将使用“跳转”指令将直线代码路径中的“无操作”修补到线外真正分支。因此,改变分支方向是昂贵的,但分支选择基本上是“免费的”。这是此优化的基本权衡。

这种低级修补机制称为“跳转标签修补”,是静态键的基础。

于 2013-09-18T07:40:13.593 回答