当前位置: 首页 > 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…...

element-ui中的el-table的summary-method(合计)的使用

场景图片&#xff1a; 图片1&#xff1a; 图片2&#xff1a; 一&#xff1a;使用element中的方法 优点&#xff1a; 直接使用summary-method方法&#xff0c;直接&#xff0c;方便 缺点&#xff1a; 只是在表格下面添加了一行&#xff0c;如果想有多行就不行了 1&#xff1a;h…...

“深入探索JVM:解析Java虚拟机的工作原理与性能优化“

标题&#xff1a;深入探索JVM&#xff1a;解析Java虚拟机的工作原理与性能优化 摘要&#xff1a;本文将深入探讨Java虚拟机&#xff08;JVM&#xff09;的工作原理和性能优化。我们将首先介绍JVM的基本组成和工作流程&#xff0c;然后重点讨论JVM内存管理、垃圾回收算法以及性…...

【后端】Core框架版本和发布时间以及.net 6.0启动文件的结构

2023年&#xff0c;第35周&#xff0c;第1篇文章。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; .NET Core 是一个跨平台的开源框架&#xff0c;用于构建现代化的应用程序。它在不同版本中有一些重要的区别和发布时间 目录 一、Core版本和…...

Linux 定时任务 crontab 用法学习整理

一、linux版本 lsb_release -a 二、crontab 用法学习 2.1&#xff0c;crontab 简介 linux中crontab命令用于设置周期性被执行的指令&#xff0c;该命令从标准输入设备读取指令&#xff0c;并将其存放于“crontab”文件中&#xff0c;以供之后读取和执行。cron 系统调度进程。…...

看板之道:如何利用Kanban优化您的项目流程

引言 在项目管理的世界中&#xff0c;如何确保任务的流畅进行并及时交付是每个团队都面临的挑战。Kanban&#xff0c;作为一种敏捷项目管理方法&#xff0c;为此提供了一个答案。它不仅提供了一种可视化的方式来跟踪任务的进度&#xff0c;还鼓励团队持续改进其工作流程&#…...

Docker的基础操作

1.安装docker服务&#xff0c;配置镜像加速器 1.1 使用yum进行安装 添加docker-ce的源信息 [rootlocalhost ~]# yum install yum-utils device-mapper-persistent-data lvm2 -y [rootlocalhost ~]# yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/doc…...

14、缓存预热+缓存雪崩+缓存击穿+缓存穿透

缓存预热缓存雪崩缓存击穿缓存穿透 ● 缓存预热、雪崩、穿透、击穿分别是什么&#xff1f;你遇到过那几个情况&#xff1f; ● 缓存预热你是怎么做到的&#xff1f; ● 如何避免或者减少缓存雪崩&#xff1f; ● 穿透和击穿有什么区别&#xff1f;它两一个意思还是截然不同&am…...

【PostGreSQL】PostGreSQL到Oracle的数据迁移

项目需要&#xff0c;有个数据需要导入&#xff0c;拿到手一开始以为是mysql&#xff0c;结果是个PostGreSQL的数据&#xff0c;于是装数据库&#xff0c;但这个也不懂呀&#xff0c;而且本系统用的Oracle&#xff0c;于是得解决迁移转换的问题。 总结下来两个思路。 1、Postg…...

jupyter notebook出现ERR_SSL_VERSION_OR_CIPHER_MISMATCH解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

前端进阶Html+css10----定位的参照对象(高频面试题)

1.relative的参照对象 1&#xff09;元素按照标准流进行排布&#xff1b; 2&#xff09;定位参照对象是元素自己原来的位置&#xff0c;可以通过left、right、top、bottom来进行位置调整&#xff1b; 2.absolute&#xff08;子绝父相&#xff09; 1&#xff09;元素脱离标准流…...

做音频的网站/百度云搜索引擎官网

写在前面 个人学习记录之作。仅供参考。 相关资料 关于多模态&#xff0c;其实这个图片已经基本上说尽了。 然后特别推荐B站李沐大神的论文讲解&#xff1a;多模态论文串讲上【论文精读46】 论文地址&#xff1a;https://arxiv.org/abs/2102.03334 论文代码地址&#xff1…...

wap网站如何做/他达拉非

假定组件文件为&#xff1a;./src/components/Books.vue//1、引入&#xff1a;import BScroll from better-scroll//2、使用<template><div class"wrapper"><ul><div v-show"downShow">加载中…………………………</div><…...

wordpress建站心得/网络推广平台有哪些公司

题意 TTT 组数据&#xff0c;每组数据给出一个 2N2N2N 个点的二分图&#xff0c;给出右边 nnn 个点的权值&#xff0c;设 f(S)f(S)f(S) 表示所有与左边集合 SSS 有连边的右边点的点权和。求 f(S)f(S)f(S) 的 gcd⁡\gcdgcd。 分析 对于右边的点&#xff1a; 如果没有连边&…...

开发区实验小学/河源seo

点击标题下「中国云报」可快速关注 编者按 云计算取得成功的标志在于&#xff0c;它就像是空气&#xff0c;没有人能够离开它&#xff0c;同时云服务商也被完全透明化。人们解决问题的方法是将技术的归于云计算&#xff0c;将应用的归于人类。 如今&#xff0c;云计算已经成为推…...

wap网站建设案例/百度推广点击一次多少钱

本文介绍如何获得微信公众平台关注用户的基本信息&#xff0c;包括昵称、头像、性别、国家、省份、城市、语言。本文的方法将囊括订阅号和服务号以及自定义菜单各种场景&#xff0c;无论是否有高级接口权限&#xff0c;都有办法来获得用户基本信息&#xff0c;而无需模拟登录。…...

做电商运营还是网站运营哪个好/网络推广有哪些方法

书中内容不会全部适合今天读了。但是历史总是惊人的相似。所以参考和学习的意义还是存在的。再说后面补写的内容也是有用的。...