zoukankan      html  css  js  c++  java
  • 宏likely和unlikely

    在源码中,宏likely和unlikely 是这么定义的(位于include/linux/compiler.h):

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

    要理解宏likely和unlikely ,很明显必须理解__builtin_expect。__builtin_expect是GCC(version>=2.9)引进的宏,其作用就是帮助编译器判断条件跳转的预期值,避免跳转造成时间浪费。拿下面的代码来说:

        if (likely(acat == 1)) //表示大多数情况下if里面是真,程序大多数直接执行if里面的程序
        而
        if (unlikely (thread_memory_magazine1_is_empty (tmem, ix)))//表示大多数情况if里面为假,程序大多数直接执行else里面的程序


        两段代码编译生成的汇编语句所使用到的跳转指令不一样,__builtin_expect实际上是为了满足在大多数情况不执行跳转指令,所以__builtin_expect仅仅是告诉编译器优化,并没有改变其对真值的判断。

    示例:

    //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.o
    
    test_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),%edi
    
    00000050 <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),%edi
    
    000000a0 <_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]$
    
  • 相关阅读:
    Windows Live Writer 语法高亮
    二十一、Java基础--------IO流之综合案例分析
    二十、Java基础--------IO流之其他对象
    十九、Java基础--------IO流之字节流
    十八、Java基础--------IO流体系以及字符流
    十七、Java基础---------集合框架之Map
    十六、Java基础---------集合框架之Set
    十五、Java基础---------集合框架体系以及List
    十四、Java基础---------String、StringBuffer、StringBuilder基本应用
    十三、Java基础---------多线程总结
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/3011401.html
Copyright © 2011-2022 走看看