分类: LINUX
2007-05-18 11:09:10
------------------------------------------------------------------include/linux/complier-gcc2.h #if __GNUC_MINOR__ < 96 ------------------------------------------------------------------include/linux/complier-gcc2.h
------------------------------------------------------------------include/linux/complier.h #define likely(x) __builtin_expect(!!(x), 1) The return value is the value of EXP, which should be an integral if (__builtin_expect (x, 0)) would indicate that we do not expect to call `foo', since we if (__builtin_expect (ptr != NULL, 1)) when testing pointer or floating-point values. 也可以写成: 上面的代码中,多数情况ptr非空,所以不期望进入printf()语句中。 unlikely比likely更优化!
/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
a mechanism by which the user can annotate likely branch directions and
expect the blocks to be reordered appropriately. Define __builtin_expect
to nothing for earlier compilers. */
#include
# define __builtin_expect(x, expected_value) (x)
#endif
/*
* Generic compiler-dependent macros required for kernel
* build go below this comment. Actual compiler/compiler version
* specific implementations come from the above header files
*/
#define unlikely(x) __builtin_expect(!!(x), 0)
------------------------------------------------------------------include/linux/complier.h
likely 和 unlikely在gcc中的定义:
-------------------------------------------------------------------info gcc 来自gcc的帮助
- Built-in Function: long __builtin_expect (long EXP, long C)
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.
expression. The value of C must be a compile-time constant. The
semantics of the built-in are that it is expected that EXP == C.
For example:
foo ();
expect `x' to be zero. Since you are limited to integral
expressions for EXP, you should use constructions such as
error ();
-------------------------------------------------------------------info gcc 来自gcc的帮助
如下面代码:
ptr = malloc(size);
if ( likely(ptr==NULL) ) /* 我们不希望ptr为空*/
{
printf("malloc memory failed!");
return -1;
}
if ( unlikely(ptr==NULL))
{
printf("malloc memory failed!");
return -1;
}
如果你希望做分支预测,则用likely,否则用unlikely.
很明显,应该对流程最常走的路径用分支预测,而相反的不要分支预测.
请大家注意likely和unlikely语义上没有区别,如果 ptr的值为NULL,则打印malloc memory failed! 返回 -1;
不同的是,从反编译的汇编语句中可以看出,对于有预读指令的cpu来说,进行了一定的优化!
首先要明确:
if(likely(value)) 等价于 if(value)
if(unlikely(value)) 也等价于 if(value)
也就是说 likely() 和 unlikely() 从阅读和理解代码的角度来看,是一样的!!!