编程中likely和计算机基本原理关系

Linux内核性能优化:likely与unlikely宏的分支预测实战 在计算机体系结构中,指令流水线与分支预测是提升CPU执行效率的核心机制。现代处理器通过预测分支路径来避免流水线停顿,但预测失败会导致清空流水线,产生数十个时钟周期的性能惩罚。这一原理在高性能编程领域尤为重要,尤其在操作系统内核、嵌入式系统等对延迟敏感的底层软件开发中。通过编译器提示优化分支布局,可以显著提升指令缓存命中率,减少预测失败。本文以Linux内核中广泛使用的likely和unlikely宏为例,深入解析如何通过__builtin_expect内建函数,将开发者的语义知识转化为代码优化,从而在错误处 阅读详情

1.概述

c/c++编程中会看到likeyly和unlikey的使用,其定义如下:

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

_builtin_expect 这个指令是 gcc 引入的。该函数作用是允许程序员将最有可能执行的分支告诉编译器,来辅助系统进行分支预测。当正确地使用了__builtin_expect后,编译器在编译过程中会根据程序员的指令,将可能性更大的代码紧跟着前面的代码,从而减少指令跳转带来的性能上的下降。

2.示例

#include <stdio.h>                                                                                                                                         
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x)  __builtin_expect(!!(x), 0)

int main(int argc, char *argv[])
{
 int n;
 n = atoi(argv[1]);

 if (likely(n > 10)){
  n = n + 2;
 } else {
  n = n - 2;
 }
 printf("%d\n", n);
 return 0;
}
~  

编译:

/arm-linux-androideabi-gcc -pie -fPIE  -g -fprofile-arcs -O2 -o likely likely.c

反汇编代码:

     fd0:   e350000a    cmp r0, #10
     fd4:   da00000f    ble 1018 <main+0x6c>
     fd8:   e1c420d8    ldrd    r2, [r4, #8]
     fdc:   e2801002    add r1, r0, #2
     fe0:   e2922001    adds    r2, r2, #1

小于10 ble跳转到1018代码处理,否则继续执行,即n+2指紧接者执行的。

把上面代码linkey替换成unlikey的反汇编代码:

  fcc:   ebffff57    bl  d30 <atoi@plt>
     fd0:   e350000a    cmp r0, #10
     fd4:   ca00000f    bgt 1018 <main+0x6c>
     fd8:   e1c421d0    ldrd    r2, [r4, #16]
     fdc:   e2401002    sub r1, r0, #2

可以看到此时大于10发生了跳转(前面是小于10),n-2是紧接着执行的。

3.原理

likely优化性能的原因主要有两个方面:

  • 根据cpu的流水线的执行原理,likely帮助编译器将大概率执行的代码紧挨着当前的pc地址,避免分支预测失败的惩罚。
  • 利用计算机的局部性原理,可以有利于将大概率执行的代码一次性加载到cache line。
C++(20):通过[[likely]]和[[unlikely]]优化编译switch 【代码】C++(20):通过[[likely]]和[[unlikely]]优化编译switch。 阅读详情

相关推荐

Android13配置selinux让system应用可读sys,proc,SN号

Android13预置的system应用,需要读/sys, /proc目录,读(SN)serial number号, 需要修改selinux配置,否则会报avc错.其修改方法会比Android11复杂一些.。

zmlovelx(帅得不敢出门 程序员群31843264) 2654

ARM CPU的推测执行(Speculative execution)

鲲鹏开发重点2––ARM CPU的推测执行(Speculative execution)-云社区-华为云预测执行(Speculative Execution)技术,它和multiple branch prediction(多分支预测)、 data flow analysis(数据流分析)三项技术,一起构成了out-of-order execution (乱序执行,OOOE)的技术基石。它是现代高性能计算的基础技术之一,广泛被应用在高端ARM CPU(包括各种定制ARM芯片:高通、Apple、etc), IB

hhcs 2437

【零基础入门哈希签名架构,从Lamport到SPHINCS+】第二集 哈希签名树 Merkle Tree Authentication

在第一集中,我们一直忽略了一个问题。设想一下,假如有一个Hacker(黑客),在截获到Sender发送给Receiver的公钥之后,把这个公钥改成Hacker自己的公钥,然后再发给Receiver,那么Receiver就会误认为这是Sender的公钥。所以我们之前所说放方案,其安全性都需要建立在一个前提下:Receiver需要确认公钥确实是Sender发出的。

m0_50572808的博客 2452

likely(x)与unlikely(x)函数,即__builtin_expect的使用

本文讲的likely()和unlikely()两个宏,在linux内核代码和一些应用中可常见到它们的身影。实质上,这两个宏是关于GCC编译器内置宏__builtin_expect的使用。 顾名思义,likely()指“很有可能”之意,而unlikely()指“不太可能”之意。那么,在实际应用中,它们代表什么?又是怎么使用的呢?下面是一篇外文翻译(加上了本人的一些理解),给出了详细答案。 likely()和unlikely() 对于linux内核代码,在条件判断语句中经常看到likely()...

随意的风的专栏 2066

计算机网络自顶向下(第八版)第一章课后习题

电路交换网络具有以下优点:资源独占性,在建立连接时,电路交换网络为通信双方独占一条物理路径,不会受到其他用户的影响。低时延,由于建立了专用路径,数据传输时延较小,适合对时延敏感的应用,如实时语音和视频通信。数据链路层:提供节点之间可靠的数据传输,主要任务是错误检测和纠正,以及数据帧的传输和访问控制。移动蜂窝网络:如4G LTE和5G,通过移动基站提供的无线信号实现移动设备的互联网接入。网络层:负责数据包的路由和转发,主要任务是通过网络选择最佳路径,进行流量控制和拥塞控制。手机,服务器,路由器,电脑;

hiahiakk的博客 2255

基于Freertos与lwip移植FreeModbusTcp协议

基于FreeRTOS的N32G457VEL7之LWIP网络协议栈移植-优快云博客。

Dd_456456的博客 3238

Linux 内核源码中likely()和unlikely()释疑

为什么80%的码农都做不了架构师?>>> ...

weixin_34146986的博客 611

【从零开始学Skynet】实战篇《球球大作战》(一):功能设计

为了能把之前在基础篇中学习到的Skynet的各种知识结合起来,所以在实战篇中,我们准备开发一个完整的游戏案例《球球大作战》,介绍分布式游戏服务端的实现方法。

我是一条寻水的鱼 2978

likely()与unlikely()函数的作用

#define likely(x)  __builtin_expect(!!(x), 1) 也就是说明x==1是“经常发生的”或是“很可能发生的”。 所以使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面 使用unlikely ,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。   以上操作是有利于cpu预取,提高预取指令的正确...

夏天Alex 1万+

手把手教你学Simulink--逆变器场景:基于Simulink的单相全桥逆变器PWM控制仿真建模

本文介绍了使用Simulink和Simscape Electrical库进行单相全桥逆变器PWM控制仿真建模的详细步骤。主要内容包括:从创建Simulink项目、添加电力电子组件、构建逆变器模型,到设置参数、运行仿真和结果分析。重点讲解了逆变器核心模块的配置、PWM信号生成、负载建模等关键环节,并提供了优化改进建议。该指南适用于电力电子初学者,通过仿真可以帮助理解单相全桥逆变器的工作原理和PWM控制技术,为实际应用和算法开发提供基础平台。

MHD0815的博客 665

5、快速入门

点击启动实例按钮,并设计一个business key,每个实例会有一个business key, 业务主键,也相当于一个流程实例唯一key,一般会与一次业务强相关,比如一个订单号 ,此处取为shopping_1;付款程序完成后会流转到物流发货任务,此时java工程的相应订阅会收到任务,并进入断点,且读到到toWhere变量。单击shopping可以进入实时流程图的执行图,此时流程流转到第一个任务,需要业务系统完成此任务,并通知引擎。添加类,分别订阅流程中的加入购物车任务和物流发货任务。

leyoliu的博客 3499

Android 本地代码中的LIKELY和UNLIKELY宏

阅读Android Frameworks中的C++代码时,经常会碰到在条件判断语句中使用了LIKELY和UNLIKELY这两个宏,找到这两个宏的定义如下: #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))   #define UNLIKELY( exp )     (__builtin_expect( (ex

tmpantian的专栏 579

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

有关likely和unlikely

在linux中判断语句经常会看到likely和unlikely,例如:if(likely(value)){}else{}简单从表面上看if(likely(value)) == if(value),if(unlikely(value)) == if(value)。也就是likely

armeasy的专栏 763

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

在linux中的likely和unlikely

在linux中判断语句经常会看到likely和unlikely,例如: if(likely(value)){ } else{ } 简单从表面上看if(likely(value)) == if(value),if(unlikely(value)) == if(value)。 这两个宏对程序运行结果没有影响,只是用于提高程序效率。其实现和gcc编译器密切相关。 具体点说,就是如果你觉

jackyding26791的专栏 550

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

linux中 likely与unlikely

ikely() 与 unlikely()是内核中定义的两个宏。位于/include/linux/compiler.h中, 具体定义如下: #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) __builtin_expect是gcc中提供的一个预处理命令,有

sufwei的专栏 570

内核中的 likely() 与 unlikely()

原文: http://blog.youkuaiyun.com/rstevens/article/details/1798561 内核中的 likely() 与 unlikely() 在 2.6 内核中,随处可以见到 likely() 和 unlikely() 的身影,那么为什么要用它们?它们之间有什么区别? 首先要明确:             if(likely(value)) 等

Huntinux 956

linux内核中:likely和unlikely函数

内核源码:linux-2.6.38.8.tar.bz2 参考文档:http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Other-Builtins.html#Other-Builtins 在Linux内核中likely和unlikely函数有两种(只能两者选一)实现方式,它们的实现原理稍有不同,但作用是相同的,下面将结合l...

weixin_33720956的博客 279

__builtin_expect 的使用

今天接触到了__builtin_expect 觉得很有作用,于是决定记下来 LIKELY和UNLIKELY的宏定义: #define LIKELY(x) __builtin_expect(!!(x),1) #define UNLIKELY(x) __builtin_expect(!!(x),0) 为什么使用了__builtin_expect 会使计算机运行速度加快 计算机使用流水线并行处理可以提高运行效率 流水线并行处理 即和工厂的工人一样,生产,加工,包装; 当 生产的每一个零件 都一样时; 加工岗位

hhhertzzz的博客 419

__builtin_expect详解

今天在ndpi的源代码里面,看到了

GrubLinux的专栏 1万+

likely(x)

#define likely(x) __builtin_expect(!!(x), 1)也就是说明x==1是“经常发生的”或是“很可能发生的”。 使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面, 使用unlikely ,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。这样有利于cpu预取,提高预取指令的正确率,因而可提高效率。

wangxiao5018的专栏 509

C++编程中的分支预测优化:探索代码效率提升的新路径

分支预测优化是C++编程中提升性能的一个重要手段。通过减少分支数量、提高分支预测准确性以及利用编译器优化等方法,我们可以有效地提升程序的执行效率。然而,需要注意的是,优化并非一蹴而就的过程,它需要我们对程序有深入的理解,并结合实际情况进行权衡和调整。在追求性能的同时,我们也应关注代码的可读性和可维护性,确保优化不会带来不必要的复杂性。

330

【Python】已解决:note: This error originates from a subprocess,and is likely not a problem with pip

已解决:note: This error originates from a subprocess,and is likely not a problem with pip。为了解决上述问题,我们可以先安装缺少的系统依赖,然后再安装Python库。这个错误提示表明,安装过程中的某个子进程出现了问题,但问题并不在。在Windows系统上,可以通过安装PostgreSQL并确保。在Python项目的开发过程中,我们经常需要使用。报错问题,确保Python库的顺利安装和使用。在系统路径中来解决该问题。

屿小夏.的知识博客 1万+

xcode arc 下使用 block警告 Capturing [an object] strongly in this block is likely to lead to a retain cyc...

xcode arc 下使用 block警告 Capturing [an object] strongly in this block is likely to lead to a retain cycle” in ARC-enabled code 解决方法: 方法一: ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[N...

weixin_34355715的博客 128

gcc 编译器 , __builtin_expect() 研究

在linux 代码中看到的 LIKELY(x), UNLIKELY(x), 其实是__builtin_expect() 测试__builtin_expect() 函数,到底是何意思?  cat hello.c #include #include //test_builtin_expect.c #define LIKELY(x) __builtin_expect(!!(x)

hjjdebug的专栏 2681
上一篇: arm/arm64函数栈帧(stackframe)结构和传参规则
下一篇: cache line提升程序性能
OS技术解密
博客等级 码龄16年 3760粉丝 189原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值