將流水線引入cpu,可以提高cpu的效率。更簡單的說,讓cpu可以預先取出下一條指令,可以提供cpu的效率。如下圖所示:
+--------------------------------
|取指令 | 執行指令 | 輸出結果
+--------------------------------
| | 取指令 | 執行
+--------------------------------
可見,cpu流水錢可以減少cpu等待取指令的耗時,從而提高cpu的效率。
如果存在跳轉指令,那麼預先取出的指令就無用了。cpu在執行當前指令時,從內存中取出了當前指令的下一條指令。執行完當前指令後,cpu發現不是要執行下一條指令,而是執行offset偏移處的指令。cpu只能重新從內存中取出offset偏移處的指令。因此,跳轉指令會降低流水線的效率,也就是降低cpu的效率。
綜上,在寫程序時應該儘量避免跳轉語句。那麼如何避免跳轉語句呢?答案就是使用__builtin_expect。
這個指令是gcc引入的,作用是"允許程序員將最有可能執行的分支告訴編譯器"。這個指令的寫法爲:__builtin_expect(EXP, N)。意思是:EXP==N的概率很大。一般的使用方法是將__builtin_expect指令封裝爲LIKELY和UNLIKELY宏。這兩個宏的寫法如下。
#define LIKELY(x) __builtin_expect(!!(x), 1) //x很可能爲真
#define UNLIKELY(x) __builtin_expect(!!(x), 0) //x很可能爲假
如下是一個實際的例子。
-
//test_builtin_expect.c
-
#define LIKELY(x) __builtin_expect(!!(x), 1)
-
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
-
int test_likely(int x)
-
{
-
if(LIKELY(x))
-
{
-
x = 5;
-
}
-
else
-
{
-
x = 6;
-
}
-
return x;
-
}
-
int test_unlikely(int x)
-
{
-
if(UNLIKELY(x))
-
{
-
x = 5;
-
}
-
else
-
{
-
x = 6;
-
}
-
return x;
-
}
運行如下命令:
gcc -fprofile-arcs -O2 -c test_builtin_expect.c
objdump -d test_builtin_expect.o
輸出的彙編碼爲:
-
<test_likely>:
-
00 push %ebp
-
01 mov %esp,%ebp
-
03 mov 0x8(%ebp),%eax
-
06 addl $0x1,0x38
-
0d adcl $0x0,0x3c
-
14 test %eax,%eax
-
16 jz 2d <test_likely+0x2d>//主要看這裏。此處的效果是eax不爲零時,不需要跳轉。即x爲真是不跳轉。
-
18 addl $0x1,0x40
-
1f mov $0x5,%eax
-
24 adcl $0x0,0x44
-
2b pop %ebp
-
2c ret
-
2d addl $0x1,0x48
-
34 mov $0x6,%eax
-
39 adcl $0x0,0x4c
-
40 pop %ebp
-
41 ret
-
42 lea 0x0(%esi,%eiz,1),%esi
-
49 lea 0x0(%edi,%eiz,1),%edi
-
<test_unlikely>:
-
50 push %ebp
-
51 mov %esp,%ebp
-
53 mov 0x8(%ebp),%edx
-
56 addl $0x1,0x20
-
5d adcl $0x0,0x24
-
64 test %edx,%edx
-
66 jne 7d <test_unlikely+0x2d>//主要看這裏。此處的效果是edx爲零時,不需跳轉。即x爲假時不跳轉。
-
68 addl $0x1,0x30
-
6f mov $0x6,%eax
-
74 adcl $0x0,0x34
-
7b pop %ebp
-
7c ret
-
7d addl $0x1,0x28
-
84 mov $0x5,%eax
-
89 adcl $0x0,0x2c
-
90 pop %ebp
-
91 ret
-
92 lea 0x0(%esi,%eiz,1),%esi
-
99 lea 0x0(%edi,%eiz,1),%edi
可見,編譯器利用程序員作出的判斷,生成了高效的彙編碼。即,跳轉語句不生效的概率很大。
參考資料:http://hi.baidu.com/uu_dou/item/e9f6f41d570d817b7a5f25c7