正在加载
请稍等

菜单

红楼飞雪 梦

15526773247

文章

Home android 嵌入式开发 Linux中的likely()和unlikely()
Home android 嵌入式开发 Linux中的likely()和unlikely()

Linux中的likely()和unlikely()

android 嵌入式开发, linux开发学习 by

今天在研究在研究android logger日志系统的时候,碰到这个unlikely函数,代码摘录如下:

DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024)
DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024)
DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024)
 
static struct logger_log * get_log_from_minor(int minor)
{
	if (log_main.misc.minor == minor)
		return &log_main;
	if (log_events.misc.minor == minor)
		return &log_events;
	if (log_radio.misc.minor == minor)
		return &log_radio;
	return NULL;
}
 
static int __init init_log(struct logger_log *log)
{
	int ret;
	ret = misc_register(&log->misc);
	if (unlikely(ret)) {
		printk(KERN_ERR "logger: failed to register misc "
		       "device for log '%s'!\n", log->misc.name);
		return ret;
	}
	printk(KERN_INFO "logger: created %luK log '%s'\n",
	       (unsigned long) log->size >> 10, log->misc.name);
	return 0;
}
 
static int __init logger_init(void)
{
	int ret;
	ret = init_log(&log_main);
	if (unlikely(ret))
		goto out;
	ret = init_log(&log_events);
	if (unlikely(ret))
		goto out;
	ret = init_log(&log_radio);
	if (unlikely(ret))
		goto out;
out:
	return ret;
}
device_initcall(logger_init);

网上查了一下,原来是gcc预定义的两个宏,在linux2.6以后的版本中随处可见。位于/include/linux/compiler.h中,具体定义如下:

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

__builtin_expect是gcc(版本>=2.96,)中提供的一个预处理命令(这个名词也是网上写的,我想叫函数更好些),有利于代码优化。gcc(version 4.4.0)具体定义如下:

long __builtin_expect (long exp, long c) [Built-in Function]

注解为:

You may use __builtin_expect to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (‘-fprofile-arcs’), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect.The return value is the value of exp, which should be an integral expression. The semantics of the built-in are that it is expected that exp == c.

它的意思是:我们可以使用这个函数人为告诉编绎器一些分支预测信息“exp==c” 是“很可能发生的”。

#define likely(x) __builtin_expect(!!(x), 1)

也就是说明x==1是“经常发生的”或是“很可能发生的”。
使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面, 使用unlikely ,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。这样有利于cpu预取,提高预取指令的正确率,因而可提高效率。

编译过程中,会将if后面{}里的内容编译到前面,else 后面{}里的内容编译到后面。若将likely换成unlikely 则正好相反。
总之,likely与unlikely互换或不用都不会影响程序的正确性。但可能会影响程序的效率。

if(likely(foo))  //认为foo通常为1
if(unlikely(foo)) //认为foo通常为0

另外内核2.6.31.5中likely和unlikely还有一种定义:

# ifndef likely
# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
# endif
# ifndef unlikely
# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
# endif

 

07 2016-01

 

我要 分享

 

 

本文 作者

 

相关 文章