gcc 编译器 , __builtin_expect() 研究

在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...)返回即为真,反之则返回值亦反之。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值