[kernel][technical points] likely & unlikely

1 篇文章 0 订阅
1 篇文章 0 订阅

一. 定义 

 

 #define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))

 #define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))

 

__builtin_constant_p(x) :

     int __builtin_constant_p (exp) [Built-in Function]
You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile time and hence that GCC can perform constantfolding on expressions involving that value. The argument of the function is the value to test. The function returns the integer 1 if the argument is known to be a compiletime constant and 0 if it is not known to be a compile-time constant. A return of 0 does not indicate that the value is not a constant, but merely that GCC cannot prove it is a constant with the specified value of the ‘-O’ option.       

 

__branch_check__() : [include/linux/compiler.h]

 

gcc specs: https://gcc.gnu.org/onlinedocs/

 

定义中包含gcc内嵌函数, 来协助提高程序设计的分支预测,优化程序. (实际上,还是需要先判断 likely/ unlikely参数 真/假 . )

unlikely 表示该条件是极少发生的;

likely表示该条件多数情况下会发生

 

二. 原理

      cpu执行是流水线形式, 会预取指令,  而编译器会根据unlikely/likely, 产生相应的代码来优化编译结果, 来符合 unlikely/likely 代码分支意愿. 

 

三 . 例子

 sources :

#include <linux/module.h>
#include <linux/init.h>


static int __init unlikely_init(void)
{
    int a = 10;
    int b = 20;

    printk("%s : entry...\n", __func__);

    if (likely(a <= b)) {
        printk("likely if case ...\n");
    } else {
        printk("likely else case ...\n");
    }

    if (unlikely(a <= b)) {
        printk("unlikely if case ...\n");
    } else {
        printk("unlikely else case ...\n");
    }

    return 0;
}

static void __exit unlikely_exit(void)
{
    printk("%s : exit...\n", __func__);

}

module_init(unlikely_init);
module_exit(unlikely_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("root@local");
MODULE_DESCRIPTION("Test for likely & unlikely");
 

makefile :

MKDIR := /lib/modules/`uname -r`/build

objs := unlikely.o

obj-m := unlikely.o

all : 
    $(MAKE) -C $(MKDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(MKDIR) SUBDIRS=$(PWD) clean
    rm -f *.ko
 

    当修改 a,b 取值的时候, 与没有使用 likely/unlikely是一样的, 使用 likely/unlikely 首先会先做参数真假判断, 其次再根据 likely/unlikely的期望, 来告诉编译器 优化代码, 从而影响CPU取指命中率, 来符合 likely/unlikely的期望. 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值