gcc 编译器 , __builtin_expect() 研究

来源:互联网 发布:淘宝客推广方法有哪些 编辑:程序博客网 时间:2024/06/04 18:29

在linux 代码中看到的 LIKELY(x), UNLIKELY(x), 其实是__builtin_expect()

测试__builtin_expect() 函数,到底是何意思?

 cat hello.c

#include <stdio.h>
#include <stdbool.h>
//test_builtin_expect.c
#define LIKELY(x) __builtin_expect(!!(x), 1)
#define UNLIKELY(x) __builtin_expect(!!(x), 0)

bool test_likely(int x)
{
    bool ret;
    if(__builtin_expect(!!(x),1)) ret=true;
    else ret = false;

    return ret;
}

bool test_unlikely(int x)
{
    bool ret;
    if(__builtin_expect(!!(x),0)) ret=true;
    else ret = false;
    return ret;
}

int main(int argc, char *argv[])
{
    bool ret;
    ret = test_likely(3);
    printf("test_likely is %d\n",ret);    
    ret = test_unlikely(3);
    printf("test_unlikely is %d\n",ret);    
    return 0;

}

编译: gcc -o hello hello.c

输出结果,

likely(3),unlikely(3) 输出都为真

likely(0),unlikely(0)输出都为假。

所以: __builtin_expect(!!(x), 1) 和 __builtin_expect(!!(x), 0) 没有区别。

 ./hello
test_likely is 1
test_unlikely is 1


我查了一下反汇编代码,__builtin_expec(x,1), __builtin_expec(x,0) 代码完全一样,

都是和0 进行比较。


000000000040052d <test_likely>:
  40052d:   55                      push   %rbp
  40052e:   48 89 e5                mov    %rsp,%rbp
  400531:   89 7d ec                mov    %edi,-0x14(%rbp)
  400534:   83 7d ec 00             cmpl   $0x0,-0x14(%rbp)
  400538:   0f 95 c0                setne  %al
  40053b:   0f b6 c0                movzbl %al,%eax
  40053e:   48 85 c0                test   %rax,%rax
  400541:   74 06                   je     400549 <test_likely+0x1c>
  400543:   c6 45 ff 01             movb   $0x1,-0x1(%rbp)
  400547:   eb 04                   jmp    40054d <test_likely+0x20>
  400549:   c6 45 ff 00             movb   $0x0,-0x1(%rbp)
  40054d:   0f b6 45 ff             movzbl -0x1(%rbp),%eax
  400551:   5d                      pop    %rbp
  400552:   c3                      retq   

0000000000400553 <test_unlikely>:
  400553:   55                      push   %rbp
  400554:   48 89 e5                mov    %rsp,%rbp
  400557:   89 7d ec                mov    %edi,-0x14(%rbp)
  40055a:   83 7d ec 00             cmpl   $0x0,-0x14(%rbp)
  40055e:   0f 95 c0                setne  %al
  400561:   0f b6 c0                movzbl %al,%eax
  400564:   48 85 c0                test   %rax,%rax
  400567:   74 06                   je     40056f <test_unlikely+0x1c>
  400569:   c6 45 ff 01             movb   $0x1,-0x1(%rbp)
  40056d:   eb 04                   jmp    400573 <test_unlikely+0x20>
  40056f:   c6 45 ff 00             movb   $0x0,-0x1(%rbp)
  400573:   0f b6 45 ff             movzbl -0x1(%rbp),%eax
  400577:   5d                      pop    %rbp
  400578:   c3                      retq   

有人说要修改编译选项才能看到差别,是为了优化才设置这个函数的。

俺网上说法加个什么 acrs profile 之类, 我试了一下还是没有看出差别,可见这个东西已经

非常不重要了,可能仅仅是为了某种优化。

就认为x 为正, __builtin_expec(x...)返回即为真,反之则返回值亦反之。

0 0