第7章 CPU前端优化
接下来讨论如何使用CPU监控特性寻找CPU上运行的代码中可被调优的位置。
标准的算法和数据结构在性能敏感型工作负载并不总能表现的很好。例如,在“扁平化”数据结构的冲击下,链表基本上快被放弃了。传统链表中的每个节点都是动态分配的,除了引入耗时的内存分配操作,还可能让链表中所有元素分散在内存中,导致随机内存访问。
二分搜索在排序数组中查找元素方面是最优的,但是该算法经常会有很多分支预测错误的问题,这就是为何线性搜索在小型(少于20个元素)整型数组上表现得最好。
本章尝试专注于CPU微架构相关的优化,而不是覆盖所有你能想到的优化机会、不过也有必要列出上层的优化点:
1. 使用开销更低的语言重写程序的性能关键部分;
2. 分析程序中使用的算法和数据结构;
3. 调优编译器参数,检查至少使用了-O3(与机器无关的优化功能)、 -march(启用针对特定CPU系列的优化功能)和-flto(启用过程间优化功能);
4. 如果问题是高度并行化的计算,考虑把程序线程化或者放到GPU上运行;
5. 当等待IO操作时,使用同步IO以避免阻塞;
6. 利用更多的RAM来减少必须使用的CPU和IO量(记忆、查找表、数据缓存、压缩等);
数据驱动优化
数据驱动的优化是最重要的调优技术之一,它基于对程序正在处理的数据的洞察,聚焦于数据的分布及其在程序中的转换方式。典型的有SOA和AOS数据布局。如果程序遍历数据结构并且只访问指端b,那么SOA会更好。然而如果程序遍历数据结构并且访问该对象的所有字段都需要进行许多操作,那么AOS会更好。因为该数据的所有成员可能都会保留在相同的缓存行里。
另一个非常重要的数据驱动的优化是“小尺寸优化”,其理念是提前为容器分配一定量的内存,以避免动态内存分配。这对元素数据上限可以预测的中小尺寸容器非常有用。
实现的优化不一定对所有平台都有效果。例如循环阻塞非常依赖系统内存的层次特征,尤其是L2和L3缓存大小。在程序将要运行的平台上测试这些变化是非常重要的。
CPU前端低效指后端在等待指令来执行,但是前端不能给后端提供指令,原因归类为2种:缓存利用率和无法从内存中获取指令。建议只有当TMA显式较高的“前端bound”指标(大于20%)时,才关注CPU前端的代码优化。
7.1 机器码布局
当编译器将源代码翻译为机器码时,它会生成一个串行的字节列。其中指令在内存中放置的偏移位置,也会反过来影响二进制文件的性能。
7.2 基本块
基本块是指只有一个入口和一个出口的指令序列。虽然基本块可以有多个前导和后继,但是在基本块中间没有任何指令可以跳出基本块,保证基本块中的每条代码只会被执行1次,能大大地减少控制流图分析和转化的问题。
7.3 基本块布局
// hot path
if (cond)coldFunc();
// hot path again
如果cond通常为真,那么就选默认布局。因为另一个布局通常做2次而不是1次跳转。但是coldFunc是一个错误处理函数,并且不太可能会被经常执行,选择保持热点代码间的直通,并且把选取分支转化为未被选取分支。
选择热点代码间的直通的布局有原因如下:
1. 未被选取的分支比被选取时耗时更少。一般情况下,Intel CPU每个时钟可以执行2个未被选择的分支,但是每2个时钟周期才能执行一个被选取的分支。
2. 更充分利用指令和微操作缓存。因为所有热点代码都是连续的,所以没有缓存行碎片化问题。
3. 被选取的分支对于读取单元来说也更耗时。每个被选取的跳转指令都意味着跳转之后的字节都是都无效的。
可以使用__builtin_expect(cond, 0)注解告诉编译器概率高低。
7.4 基本块对齐
性能会由于指令在内存中的偏移量而发生明显的变化。若循环跨越多条缓存行,可能会导致CPU前端出现性能问题,所以我们可以使用nop指令将循环指令向前移动,以便让整个循环驻留在一条缓存行中。
LLVM使用-mllvm-align-all-blocks对齐基本块,注意它们可能导致性能劣化,插入nop指令,会增加程序的开销,尤其是当它们处于关键路径上。nop指令不需要被执行,但是它们仍然需要从内存中读取、解码和退休,额外地消耗前端数据结构和用于记账的缓冲区空间。
为了细粒度地控制对齐,还可以使用ALIGN汇编指令,针对实验场景,开发人员先生成汇编列表,然后插入ALIGN指令。
7.5 函数拆分
函数拆分的设想是把热点代码和冷代码区分开,该优化对在热路径中具有复杂CFG和大量冷代码的函数是有益的。
void foo(bool cond1, bool cond2) {// hot pathif (cond1) {//large amount of cold code cond1}// hot pathif (cond2) {//large amount of cold code cond2}
}// 优化后
void foo(bool cond1, bool cond2) {// hot pathif (cond1) {cold1()}// hot pathif (cond2) {cold2()}
}void cold1() __attribute_((noinline)) { // cold code (1)};
void cold2() __attribute_((noinline)) { // cold code (2)};
图中我们只保存了热路径的call指令,所以下一个热点代码指令可能会驻留在相同的缓存行,提升CPU前端数据结构(指令缓存和DSB)的利用率。留意其中的另一个重要思想:禁止内联冷函数。最后,创建的新函数要放在.text段之外。如果从不调用该函数,俺么它不会在运行时加载到内存中,所以可能会改善内存占用情况。
7.6 函数分组
热点函数可以被分组在一起以进一步提升CPU前端缓存的利用率,减少需要读取缓存行的数量。
链接器负责程序在最终的二进制输出中所有函数的排列布局。LLVM的LLD链接器使用--symbol-ordering-file优化函数的布局。
HFSort工具基于剖析数据自动生成分区排序文件。
7.7 基于剖析文件的编译优化
大多数编译器都有一组转换功能,可以根据反馈给它们的剖析数据来调整算法,被称为基于剖析文件的编译优化Profile Directed Optimization,PGO。
剖析数据生成方式有二:代码插桩核基于采样的剖析。
1. 先利用LLVM编译器使用-fprofile-instr-generate告诉编译器生成插桩代码。然后LLVM编译器使用-fprofile-inst-use利用剖析数据重新编译程序,并生成PGO调优的二进制文件。
2. 基于采样生成编译器所需的剖析数据。然后AutoFDO把linux perf生成的采样数据转换为GCC和LLVM的编译器可以理解的形式。不过编译器会假设所有负载的表现都一样。
7.8 对ITLB的优化
内存地址中虚地址到物理地址的翻译是前端性能调优的另一个重要领域。通过把应用程序的性能关键代码部分地映射到大页上,可以减少ITLB压力。这需要重新链接二进制文件,在合适的页边界对齐代码段。除了使用大页,用于优化指令缓存性能的标准技术也可以提升ITLB性能,即重排函数让热点函数更集中,通过LTO/IPO减小热点区域的大小,使用PGO并避免过度内联。
7.9 总结
| 转换 | 如何转换 | 优点 | 应用场景 | 执行者 |
| 基本块布局 | 维护热点代码的直通 | 未被选取的分支耗时更少;缓存利用率更高 | 任何代码,尤其是由很多分支的代码 | 编译器 |
| 基本块对齐 | 使用NOP指令对热点代码进行移位 | 缓存利用率更高 | 热点循环 | 编译器 |
| 函数拆分 | 把冷代码拆分出来并放到单独的函数中 | 缓存利用率更高 | 当在热代码间存在大段冷代码的函数时,具有复杂CFG的函数 | 编译器 |
| 函数分组 | 把热点函数分组到一起 | 缓存利用率更高 | 有很多热点小函数 | 链接器 |
相关文章:
第7章 CPU前端优化
接下来讨论如何使用CPU监控特性寻找CPU上运行的代码中可被调优的位置。 标准的算法和数据结构在性能敏感型工作负载并不总能表现的很好。例如,在“扁平化”数据结构的冲击下,链表基本上快被放弃了。传统链表中的每个节点都是动态分配的,除了…...
idea新建Java-maven项目时,出现Dependency‘xxx(jar包名)‘ not found的解决方案
项目场景: 项目场景:使用idea创建maven项目时,导入简单依赖时(本文以mysql-connector-java为例)。 问题描述 问题: 首先,在创建新的maven项目中,出现下列两种情况: &am…...
STM32--USART串口
文章目录 通信接口串口通信硬件电路电平标准参数时序 USART主要特性框图 数据帧发送器 波特率发生器SWART串口发送与接收工程串口收发数据包 通信接口 通信接口是指连接中央处理器(CPU)和标准通信子系统之间的接口,用于实现数据和控制信息在不…...
2023年Java毕业设计题目推荐,怎样选题?500道毕业设计题目推荐
大家好,我是程序员徐师兄,最近有很多同学咨询,说毕业设计了,不知道选怎么题目好,有哪些是想需要注意的。 今天,我整理了一些Java毕业设计的题目,可以参考一下,希望对大家有所帮助 文章目录 一、…...
基于数据湖的多流拼接方案-HUDI概念篇
目录 一、为什么需要HUDI? 1. 传统技术选型存在哪些问题? 2. Hudi有什么优点? 基于 Hudi Payload 机制的多流拼接方案: 二、HUDI的应用场景 1. 什么场景适合使用hudi? 2. 什么场景不适合使用hudi? …...
OpenCV基础知识(5)— 几何变换
前言:Hello大家好,我是小哥谈。OpenCV中的几何变换是指改变图像的几何结构,例如大小、角度和形状等,让图像呈现出缩放、翻转、旋转和透视效果。这些几何变换操作都涉及复杂、精密的计算。OpenCV将这些计算过程都封装成了非常灵活的…...
Linux下源码安装MySQL 8.0
MySQL 8.0源码安装 环境准备步骤 环境准备 Linux环境,本文基于CentOS 8 MySQL安装包,本文基于MySQL 8.1,以下为带boost MySQL 8.1源码下载地址: https://dev.mysql.com/get/Downloads/MySQL-8.1/mysql-boost-8.1.0.tar.gz 步骤…...
大聪明教你学Java | 深入浅出聊 Java 内存模型
前言 🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。 🍊支持作者: 点赞👍、关注💖、留言💌~ 在多线程环境下,多个线程同时访问共享数据可能导致一系列问题,如数据不一致、竞态条件和死锁等…...
SAP ABAPG开发屏幕自动生成日期的搜索帮助
代码如下: REPORT z_jason_test_f4 . TABLES: s031. PARAMETER p_spmon TYPE spmon DEFAULT sy-datum0(6) OBLIGATORY. SELECT-OPTIONS s_spmon FOR s031-spmon DEFAULT sy-datum0(6) OBLIGATORY. AT SELECTION-SCREEN ON VALUE-REQUEST…...
leetcode 674. 最长连续递增序列
2023.8.24 与最长递增子序列 类似,不同的是, 本题要求连续序列,所以不需要第二层遍历比较之前所有的元素了,只需要比较上一个元素i-1。 dp[i]的含义为:以nums[i]元素为结尾的序列的最长递增子序列。 注意这里是以i为结…...
Mysql简短又易懂
MySql 连接池:的两个参数 最大连接数:可以同时发起的最大连接数 单次最大数据报文:接受数据报文的最大长度 数据库如何存储数据 存储引擎: InnoDB:通过执行器对内存和磁盘的数据进行写入和读出 优化SQL语句innoDB会把需要写入或者更新的数…...
vue 简单实验 v-model 变量和htm值双向绑定
1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"two-way-binding"><p>{{ message }}</p><input v-model"message" /> </div> <script>…...
测试框架pytest教程(8)失败重试-pytest-rerunfailures
pytest-rerunfailures是一个pytest插件,用于重新运行失败的测试用例。当测试用例在第一次运行时失败,该插件会自动重新运行指定次数的失败用例,以提高稳定性和减少偶发性错误的影响。 要使用pytest-rerunfailures插件,需要按照以…...
6个主流的工业3D管道设计软件
3D 管道设计软件是大多数行业工程工作的主要部分,例如: 电力、石油和天然气、石化、炼油厂、纸浆和造纸、化学品和加工业。 全球各工程公司使用了近 50 种工厂或管道设计软件。 每个软件都有优点和缺点,包括价格点。 EPC 和业主部门当前的趋势…...
基于微信小程序的垃圾分类系统设计与实现(2.0 版本,附前后端代码)
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 1 简介 视频演示地址: 基于微信小程序的智能垃圾分类回收系统,可作为毕业设计 小…...
基础论文学习(4)——CLIP
《Learning Transferable Visual Models From Natural Language Supervision》 CLIP的英文全称是Contrastive Language-Image Pre-training,即一种基于对比文本-图像对的预训练模型。CLIP是一种基于对比学习的多模态模型,与CV中的一些对比学习方法如moc…...
SpringBoot利用ConstraintValidator实现自定义注解校验
一、前言 ConstraintValidator是Java Bean Validation(JSR-303)规范中的一个接口,用于实现自定义校验注解的校验逻辑。ConstraintValidator定义了两个泛型参数,分别是注解类型和被校验的值类型。在实现ConstraintValidator接口时&…...
十、pikachu之php反序列化
文章目录 1、php反序列化概述2、实战3、关于Magic function4、__wakeup()和destruct() 1、php反序列化概述 在理解这个漏洞前,首先搞清楚php中serialize(),unserialize()这两个函数。 (1)序列化serialize():就是把一个…...
PHP“牵手”拼多多商品详情数据获取方法,拼多多API接口批量获取拼多多商品详情数据说明
拼多多商品详情接口 API 是开放平台提供的一种 API 接口,它可以帮助开发者获取拼多多商品的详细信息,包括商品的标题、描述、图片等信息。在拼多多电商平台的开发中,拼多多详情接口 API 是非常常用的 API,因此本文将详细介绍拼多多…...
前端面试:【Redux】状态管理的精髓
嘿,亲爱的Redux探险家!在前端开发的旅程中,有一个强大的状态管理工具,那就是Redux。Redux是一个状态容器,它以一种可预测的方式管理应用的状态,通过Store、Action、Reducer、中间件和异步处理等核心概念&am…...
量子行走:从理论到Python实现——量子力学原理与Qubit物理
目录 2. 量子力学原理与Qubit物理 2.1 量子比特的物理实现 2.1.1 双能级系统建模 2.1.2 布洛赫球表示与可视化 2.2 叠加与纠缠现象 2.2.1 量子叠加原理 2.2.2 量子纠缠理论 2.3 量子测量与退相干 2.3.1 测量公设的实现 2.3.2 噪声与退相干机制 2. 量子力学原理与Qubi…...
极简安装方案:树莓派部署OpenClaw轻量版对接云端Qwen3-32B
极简安装方案:树莓派部署OpenClaw轻量版对接云端Qwen3-32B 1. 为什么选择树莓派OpenClaw轻量版? 去年夏天,我突发奇想:能不能用树莓派做个24小时在线的AI管家?既能控制智能家居,又能处理简单办公任务。但…...
OpenCore辅助工具(OCAT)全攻略:从配置到优化的黑苹果必备工具
OpenCore辅助工具(OCAT)全攻略:从配置到优化的黑苹果必备工具 【免费下载链接】OCAuxiliaryTools Cross-platform GUI management tools for OpenCore(OCAT) 项目地址: https://gitcode.com/gh_mirrors/oc/OCAuxiliaryTools 核心价值&…...
大厂速报:小红书期权涨麻,字节年终暴击,AI赛道卷疯了
互联网圈没有岁月静好,只有暗潮涌动——大厂裁员传闻从未断档,AI内卷卷到凌晨三点,打工人一边焦虑KPI,一边蹲守大厂福利,有人靠期权实现财富跃迁,有人被组织调整撞个正着。一、核心福利|打工人狂…...
无人机控制中的模糊控制:一维与二维模糊控制及其实现要点
无人机 控制方面 模糊控制 有一维模糊和二维模糊两种,文字说明资料已遗失,数学模型可以根据仿真图推导,直接运维simulink会报错,是因为没有导入模糊规则,在运行simulink之前需要在命令窗口输入workreadfis work.fis ,这…...
Realtek RTL8125 2.5GbE网卡驱动技术指南
Realtek RTL8125 2.5GbE网卡驱动技术指南 【免费下载链接】realtek-r8125-dkms A DKMS package for easy use of Realtek r8125 driver, which supports 2.5 GbE. 项目地址: https://gitcode.com/gh_mirrors/re/realtek-r8125-dkms 1. 问题诊断:网络设备识别…...
Burp Suite实战进阶:用LingJing内置的burp-labs靶机打通从入门到专家22关(含解题思路)
Burp Suite实战进阶:用LingJing内置的burp-labs靶机打通从入门到专家22关(含解题思路) 在网络安全领域,Burp Suite无疑是渗透测试工程师最得力的工具之一。然而,很多学习者在掌握了基础操作后,往往会陷入&q…...
便携激光云高仪:精确测量云底高度、云层厚度等关键参数
便携激光云高仪是一种用于测量云层高度、厚度及分布情况的气象观测设备,广泛应用于气象监测、航空安全、环境研究等领域。其便携式设计特别适合野外作业和临时观测需求。设备通过激光脉冲探测云底高度,并实时分析云层垂直结构,为气象预报、灾…...
5分钟搞定PaddleOCR文字识别:Python版保姆级教程(附完整代码)
5分钟极速上手PaddleOCR:Python实战指南与避坑手册 第一次接触OCR技术时,我被那些复杂的配置参数和晦涩的文档吓退了三次。直到发现PaddleOCR这个"开箱即用"的工具,才明白原来文字识别可以如此简单。本文将带你用最直接的方式&…...
建议收藏|盘点2026年顶尖配置的AI论文平台
一天写完毕业论文在2026年已不再是天方夜谭。以下是2026年最炸裂、实测能大幅提速的AI论文平台,覆盖选题构思、文献分析、内容生成、格式排版四大核心场景,帮你高效搞定论文。 一、全流程王者:一站式搞定论文全链路(一天定稿首选&…...
