当前位置: 首页 > news >正文

第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插件&#xff0c;用于重新运行失败的测试用例。当测试用例在第一次运行时失败&#xff0c;该插件会自动重新运行指定次数的失败用例&#xff0c;以提高稳定性和减少偶发性错误的影响。 要使用pytest-rerunfailures插件&#xff0c;需要按照以…...

6个主流的工业3D管道设计软件

3D 管道设计软件是大多数行业工程工作的主要部分&#xff0c;例如&#xff1a; 电力、石油和天然气、石化、炼油厂、纸浆和造纸、化学品和加工业。 全球各工程公司使用了近 50 种工厂或管道设计软件。 每个软件都有优点和缺点&#xff0c;包括价格点。 EPC 和业主部门当前的趋势…...

基于微信小程序的垃圾分类系统设计与实现(2.0 版本,附前后端代码)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 1 简介 视频演示地址&#xff1a; 基于微信小程序的智能垃圾分类回收系统&#xff0c;可作为毕业设计 小…...

基础论文学习(4)——CLIP

《Learning Transferable Visual Models From Natural Language Supervision》 CLIP的英文全称是Contrastive Language-Image Pre-training&#xff0c;即一种基于对比文本-图像对的预训练模型。CLIP是一种基于对比学习的多模态模型&#xff0c;与CV中的一些对比学习方法如moc…...

SpringBoot利用ConstraintValidator实现自定义注解校验

一、前言 ConstraintValidator是Java Bean Validation&#xff08;JSR-303&#xff09;规范中的一个接口&#xff0c;用于实现自定义校验注解的校验逻辑。ConstraintValidator定义了两个泛型参数&#xff0c;分别是注解类型和被校验的值类型。在实现ConstraintValidator接口时&…...

十、pikachu之php反序列化

文章目录 1、php反序列化概述2、实战3、关于Magic function4、__wakeup()和destruct() 1、php反序列化概述 在理解这个漏洞前&#xff0c;首先搞清楚php中serialize()&#xff0c;unserialize()这两个函数。 &#xff08;1&#xff09;序列化serialize()&#xff1a;就是把一个…...

PHP“牵手”拼多多商品详情数据获取方法,拼多多API接口批量获取拼多多商品详情数据说明

拼多多商品详情接口 API 是开放平台提供的一种 API 接口&#xff0c;它可以帮助开发者获取拼多多商品的详细信息&#xff0c;包括商品的标题、描述、图片等信息。在拼多多电商平台的开发中&#xff0c;拼多多详情接口 API 是非常常用的 API&#xff0c;因此本文将详细介绍拼多多…...

前端面试:【Redux】状态管理的精髓

嘿&#xff0c;亲爱的Redux探险家&#xff01;在前端开发的旅程中&#xff0c;有一个强大的状态管理工具&#xff0c;那就是Redux。Redux是一个状态容器&#xff0c;它以一种可预测的方式管理应用的状态&#xff0c;通过Store、Action、Reducer、中间件和异步处理等核心概念&am…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解

文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...