CPU性能优化--基于处理器事件的采样

基于处理器事件的采样processor event based sampling PEBS 是CPU的另一种非常有用的特性,PEBS被用来在每个采样点获取更多的补充数据。在Intel处理器中,PEBS是在NetBrust微架构开始i引入的,在AMD处理器中,类似的特性叫基于指令的采样IBS。

这些补充数据有定义好的格式,为PEBS配置性能计数器之后,处理器会保存PEBS缓冲区的内容,并将之转存到内存中。记录的信息包括处理器的架构状态,例如,通用的寄存器,EAX, EBX, ESP等,指令指针寄存器EIP和标志寄存器EFLAGS 等的状态,

用户可以通过dmesg命令来检查PEBS是否启用。

字节偏移 字段 字节偏移 字段

EFLAGS R11

EIP R12

RAX R13

EBX R14

ECX R15

EDX

ESI

EDI

EBP

ESP

linux perf工具没像处理LBR那样把原始的PEBS内容导出来,它基于具体需要处理PEBS记录并只导出部分数据。所以,不可能通过linux perf工具导出原始PEBS数据。linux perf工具只提供一些从原始采样数据处理后的PEBS数据,可以通过命令perf report -D获得。要获得原始PEBS记录,可以使用pebs-grabber 工具。

6.3.1 精准事件

当出现溢出导致的中断时,处理器需要一定的时间来停止执行并标记触发溢出的指令。这对现代复杂的乱序执行CPU架构来说,实现起来非常困难。

引入滑动概念,被定义为触发性能事件的IP与标记事件的IP在PEBS记录的IP字段间的距离。滑动使得寻找导致性能问题的指令变得困难,实际上会造成性能问题。想象一个缓存未命中次数很多的程序,热点汇编代码如下load1,load2,load3 性能剖析工具将load3识别为导致高缓存未命中的指令。然而实际上load1才是,通常,这会给新手带来很多困惑,感兴趣的读者可以在intel Developer Zone website找到这类问题潜在的原因的更多信息。

滑动的问题通过让处理器自身记录PEBS记录中的指令地址得到了缓解。PEBS记录中EventingIP字段表示的就是导致性能事件的指令,需要硬件的支持,并且通过只支持一部分性能事件,这样的事件被称为精准事件。具体微架构的精准事件详见,下面列出了Skylake 微架构的精确事件。

INST_RETIRED

OTHER_ASSISTS

BR_INST_RETIRED

BR_MISP_RETIRED

FRONTEND_RETIRED

HLE_RETIRED

RTM_RETIRED

MEM_INST_RETIRED

MEM_LOAD_RETIRED

MEM_LOAD_L3_HIT_RETIRED

TMA分析方法严重依赖精准事件来定位低效率执行代码的具体位置。

easyperf 博客的一篇文章介绍了使用精准事件缓解滑动的例子。linux perf工具的用户需要在事件后面增加ppp后缀来启动精准标注。

perf record -e cpu/event=0xd1

6.3.2 降低采样开销

频繁产生中断并让分析工具采集被中断服务过程中的程序状态,都需要与操作系统交互,这会消化非常多系统资源。这也是为何有些硬件允许无中断的自动对特定的缓冲区采样多次。只有当特定的缓冲区满了,处理器才会发起中断把缓冲区内容刷新到内存中。这种方式的开销相比传统的基于中断的采样开销要低。

为PEBS配置性能计数器后,计数器的溢出条件会支撑PEBS机制,对溢出后的事件,处理器会生成PEBS事件。在PEBS事件中,处理器会把PEBS记录存储到PEBS缓冲区,然后清理计数器溢出状态并恢复到初始值。如果缓冲区满了,CPU将发起一次中断

注意,PEBS缓冲区位于主存内,大小可以设置,性能分析工具的工作时分配和配置内存区域,供CPU导出PEBS记录。

6.3.3 分析内存访问

内存访问时很多应用程序性能的关键因素,有了PEBS,就有可能收集程序中的内存访问相关的详细信息,数据地址剖析可以实现这个功能。为了提供被采样加载和存储指令的更多信息,利用了PEBS特性中的如下字段,

数据线性地址0x98

数据源编码0xa0

时延值 0xA8

如果性能事件支持数据线性地址功能并且启用了该功能,CPU会导出被采样内存访问的地址和时延。请注意,这个功能不会记录所有的存储和加载指令,否则会开销非常大。所以,它只是对内存访问进行采样,例如,大概只会分析1000次访问中的一次,你可以根据需要设置每秒的采样次数。

PEBS扩展的重要使用场景之一的就是检测真伪共享,linux perf 工具严重依赖DLA数据来寻找有争议,可能导致真伪共享内存访问,

此外有了数据地址剖析工具的帮助,用户可以获得程序中内存访问的一般统计信息:

从上面的输出,我们可以看到程序的加载指令有8%通过L1缓存实现,15%通过 DRAM实现。

相关推荐
Zzzzzxl_1 天前
互联网大厂前端面试实录:HTML5、ES6、Vue/React、工程化与性能优化全覆盖
性能优化·vue·es6·react·html5·前端面试·前端工程化
芝麻开门-新起点1 天前
Flutter 移动端性能优化指南:内存、电量与 UI 渲染
flutter·ui·性能优化
奔跑的露西ly1 天前
【HarmonyOS NEXT】常见的性能优化
华为·性能优化·harmonyos
007php0071 天前
某游戏互联网大厂Java面试深度解析:Java基础与性能优化(一)
java·数据库·面试·职场和发展·性能优化·golang·php
wuk9981 天前
Webpack技术深度解析:模块打包与性能优化
前端·webpack·性能优化
数据库生产实战1 天前
Oracle RAC灾备环境UNDO表空间管理终极指南:解决备库修改难题与性能优化实战
数据库·oracle·性能优化
山河亦问安1 天前
Spring Boot异步接口性能优化:从单线程到高并发的优化历程
spring boot·后端·性能优化
海边夕阳20061 天前
PostgreSQL性能调优:解决表膨胀、索引碎片和无效索引问题
数据库·经验分享·postgresql·性能优化
腾飞开源1 天前
09_FastMCP 2.x 中文文档之FastMCP高级功能服务器组成详解
性能优化·代理服务器·模块化设计·fastmcp 2.x中文文档·服务器组合·前缀规则·标签过滤
Jinkxs2 天前
仓颉语言性能优化指南:实测对比,让鸿蒙应用运行效率提升 40%
华为·性能优化·harmonyos