久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3572|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

__builtin_expect詳解

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:72519 發(fā)表于 2015-1-23 19:25 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
在GTK+2.0源碼中有很多這樣的宏:G_LIKELY和G_UNLIKELY。比如下面這段代碼:
if (G_LIKELY (acat == 1))       /* allocate through magazine layer */
      {
        ThreadMemory *tmem = thread_memory_from_self();
        guint ix = SLAB_INDEX (allocator, chunk_size);
        if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix)))
          {
            thread_memory_swap_magazines (tmem, ix);
            if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix)))
              thread_memory_magazine1_reload (tmem, ix);
          }
        mem = thread_memory_magazine1_alloc (tmem, ix);
      }在源碼中,宏G_LIKELY和G_UNLIKELY 是這么定義的:
#define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 1))
  #define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 0))宏_G_BOOLEAN_EXPR的作用是把expr轉(zhuǎn)換為0和1,即真假兩種。要理解宏G_LIKELY和G_UNLIKELY ,很明顯必須理解__builtin_expect。__builtin_expect是GCC(version>=2.9)引進的宏,其作用就是幫助編譯器判斷條件跳轉(zhuǎn)的預(yù)期值,避免跳轉(zhuǎn)造成時間亂費。拿上面的代碼來說:
if (G_LIKELY (acat == 1))      //表示大多數(shù)情況下if里面是真,程序大多數(shù)直接執(zhí)行if里面的程序

if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix)))//表示大多數(shù)情況if里面為假,程序大多數(shù)直接執(zhí)行else里面的程序
可能大家看到還是一頭霧水,看下面一段就會明白其中的樂趣啦;
//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;
}[lammy@localhost test_builtin_expect]$ gcc -fprofile-arcs -O2 -c test_builtin_expect.c
[lammy@localhost test_builtin_expect]$ objdump -d test_builtin_expect.otest_builtin_expect.o:       file format elf32-i386
Disassembly of section .text:00000000 <test_likely>:
     0: 55                      push     %ebp
     1: 89 e5                   mov      %esp,%ebp
     3: 8b 45 08                mov      0x8(%ebp),%eax
     6: 83 05 38 00 00 00 01  addl     $0x1,0x38
     d: 83 15 3c 00 00 00 00  adcl     $0x0,0x3c
  14: 85 c0                   test     %eax,%eax
  16: 74 15                   je       2d <test_likely+0x2d>//主要看這里
  18: 83 05 40 00 00 00 01  addl     $0x1,0x40
  1f: b8 05 00 00 00          mov      $0x5,%eax
  24: 83 15 44 00 00 00 00  adcl     $0x0,0x44
  2b: 5d                      pop      %ebp
  2c: c3                      ret      
  2d: 83 05 48 00 00 00 01  addl     $0x1,0x48
  34: b8 06 00 00 00          mov      $0x6,%eax
  39: 83 15 4c 00 00 00 00  adcl     $0x0,0x4c
  40: 5d                      pop      %ebp
  41: c3                      ret      
  42: 8d b4 26 00 00 00 00  lea      0x0(%esi,%eiz,1),%esi
  49: 8d bc 27 00 00 00 00  lea      0x0(%edi,%eiz,1),%edi00000050 <test_unlikely>:
  50: 55                      push     %ebp
  51: 89 e5                   mov      %esp,%ebp
  53: 8b 55 08                mov      0x8(%ebp),%edx
  56: 83 05 20 00 00 00 01  addl     $0x1,0x20
  5d: 83 15 24 00 00 00 00  adcl     $0x0,0x24
  64: 85 d2                   test     %edx,%edx
  66: 75 15                   jne      7d <test_unlikely+0x2d>//主要看這里
  68: 83 05 30 00 00 00 01  addl     $0x1,0x30
  6f: b8 06 00 00 00          mov      $0x6,%eax
  74: 83 15 34 00 00 00 00  adcl     $0x0,0x34
  7b: 5d                      pop      %ebp
  7c: c3                      ret      
  7d: 83 05 28 00 00 00 01  addl     $0x1,0x28
  84: b8 05 00 00 00          mov      $0x5,%eax
  89: 83 15 2c 00 00 00 00  adcl     $0x0,0x2c
  90: 5d                      pop      %ebp
  91: c3                      ret      
  92: 8d b4 26 00 00 00 00  lea      0x0(%esi,%eiz,1),%esi
  99: 8d bc 27 00 00 00 00  lea      0x0(%edi,%eiz,1),%edi000000a0 <_GLOBAL__I_65535_0_test_likely>:
  a0: 55                      push     %ebp
  a1: 89 e5                   mov      %esp,%ebp
  a3: 83 ec 08                sub      $0x8,%esp
  a6: c7 04 24 00 00 00 00  movl     $0x0,(%esp)
  ad: e8 fc ff ff ff          call     ae <_GLOBAL__I_65535_0_test_likely+0xe>
  b2: c9                      leave  
  b3: c3                      ret      
[lammy@localhost test_builtin_expect]$兩個函數(shù)編譯生成的匯編語句所使用到的跳轉(zhuǎn)指令不一樣,仔細分析下會發(fā)現(xiàn)__builtin_expect實際上是為了滿足在大多數(shù)情況不執(zhí)行跳轉(zhuǎn)指令,所以__builtin_expect僅僅是告訴編譯器優(yōu)化,并沒有改變其對真值的判斷。
這種用法在linux內(nèi)核中也經(jīng)常用到,國外也有一篇相關(guān)的文章,大家不妨看看:http://kernelnewbies.org/FAQ/LikelyUnlikely
不知大家注意到?jīng)]有,我在生產(chǎn)匯編時用的是gcc -fprofile-arcs -O2 -c test_builtin_expect.c,而不是gcc -O2 -c test_builtin_expect.c,具體可以參考http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久午夜精品 | 久久国产精品精品国产色婷婷 | 狠狠干天天干 | 日韩精品一区二区三区视频播放 | 欧美亚洲高清 | 一级大黄 | 久久天天躁狠狠躁夜夜躁2014 | 91亚洲国产成人精品一区二三 | 久久这里只有精品首页 | 国产成人精品久久二区二区 | 亚洲一区电影 | 不卡一区二区三区四区 | 99视频在线免费观看 | 欧美一区二区三区免费电影 | 伊人色综合久久天天五月婷 | 紧缚调教一区二区三区视频 | 国产欧美一区二区三区另类精品 | 毛片99 | 国产欧美久久一区二区三区 | 中文字幕色站 | 国产精品一区二区久久久久 | 亚洲视频一区在线观看 | 久草网站| av在线免费网站 | 在线欧美 | 成人一区二区三区在线观看 | 国产精品成人国产乱 | 在线午夜 | 久久99精品久久久久久青青日本 | 中文字幕亚洲一区 | 一区二区三区视频播放 | 日日夜夜草 | 在线看片国产 | 日本韩国电影免费观看 | 精精国产xxxx视频在线播放7 | 天堂中文在线播放 | 亚洲精品女人久久久 | 中文字幕亚洲欧美日韩在线不卡 | 欧美精品综合在线 | 99久久久久 | 91久久久久久久 |