问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

CPU性能分析方法论

创作时间:
作者:
@小白创作中心

CPU性能分析方法论

引用
1
来源
1.
https://www.cnblogs.com/cilinmengye/p/18546908

CPU性能分析是计算机科学中的一个重要领域,它帮助我们理解程序在CPU上的执行效率,并找出性能瓶颈。本文将深入探讨CPU性能分析方法论,包括指令流水线与分支预测、NUMA、TMA基本概念、TMA分析原理、TMA指标和计算原理、如何判断性能瓶颈以及优化指导等内容。


from pixiv

指令流水线与分支预测

指令流水线(英语:Instruction pipeline)是为了让计算机和其它数字电子设备能够加速指令的通过速度(单位时间内被执行的指令数量)而设计的技术。
流水线在处理器的内部被组织成层级,各个层级的流水线能半独立地单独运作。每一个层级都被管理并且链接到一条“链”,因而每个层级的输出被送到其它层级直至任务完成。

from 指令流水线wiki

上述说的流水线级数在此图上为4。

指令执行中产生一个“打嗝”(hiccup),在流水线中生成一个没有实效的气泡

条件分支指令通常具有两路后续执行分支。即不采取(not taken)跳转,顺序执行后面紧挨JMP的指令;以及采取(taken)跳转到另一块程序内存去执行那里的指令。是否条件跳转,只有在该分支指令在指令流水线中通过了执行阶段(execution stage)才能确定下来。

如果后来发现分支预测错误,那么流水线中推测执行的那些中间结果全部放弃,重新获取正确的分支路线上的指令开始执行。在分支预测失败时浪费的时间是从取指令到执行完指令(但还没有写回结果)的流水线的级数。

分支预测不同于“分支目标预测”(Branch target predictor)。后者是指对指令高速缓存中的内容,检测出其中的条件跳转指令与无条件跳转指令,然后为指令高速缓存预装入(prefetch)相应的跳转目标代码块。

即分支预测投机的指令是真正会执行的。

NUMA(Non-Uniform Memory Access)

  1. 什么是NUMA,我们为什么要了解NUMA

上述资料讲解了UMA(Uniform Memory Architecture)的特点与不足,从而引出NUMA。

同时讲解了CPU上socket,core,thread,node重要概念。

lscpu

命令查看socket,core,thread,nod相关信息

numactl -H

命令查看NUMA相关信息(数量,布局等)

  1. 十年后数据库还是不敢拥抱NUMA?

博客2用实验证明了NUMA绑核及其重要性

  1. CPU Utilization is Wrong

博客2,3 解释到如

top(1)

这样的性能分析工具中显示的

%CPU

指标当其值较高时,并不能代表处理器达到了瓶颈,而是表明处理器已经在

各尽所能

了。

正如博客3中的这张图,有可能CPU是被阻塞等待内存I/O:

我们若真正想要看到处理器是否达到极限,应该去看IPC(instructions per cycle )这个指标。

perf stat

命令可以做到这一点。

现代处理器一般最高速度是 IPC 为 4.0。这也称为 4 宽,指的是指令提取/解码路径。这意味着,CPU 可以在每个时钟周期退出(完成)四条指令。

如果使用

perf stat

观察到如下内容,则说明CPU在运行某程序上只使用了它

0.78 ÷ 4 × 100% = 19.5%

的"力气":


 1,118,336,816,068      instructions              #    0.78  insns per cycle          (75.01%)  

TMA基本概念

TMA是什么?

Top-down Microarchitecture Analysis,是对CPU性能瓶颈进行分析和优化的方法论。

Top-down是基于事件指标的层次组织。

从上图可以初步窥见,所谓事件是像缓存未命中事件、分支预测失败等影响CPU性能的事情。

这套方法论的计算基于流水线资源,通过计算占据流水线资源的百分比来评定事件的性能。

数据来源来自PMUs(片上性能监控单元),PMUs 是 CPU 内核中的专用逻辑块,用于记录计算系统上发生的特定硬件事件。 这些事件可能是缓存遗漏或分支错误预测。 我们可以观察到这些事件,并将它们组合起来创建有用的高级指标,如 CPI 。

基础概念:

前端和后端(the Front-end and the Back-end)

the Front-end:前端负责获取架构指令中表示的程序代码,并将其解码为一个或多个称为微操作(micro-ops (uOps)),uOps 在称为分配(Allocation)的过程中被馈送到后端。

the Back-end: 分配后,后端负责监视 uOp 的数据操作数何时可用,并在可用的执行单元中执行 uOp。

retire

uOp执行完成称为退休(retirement),此时 uOp 的结果被提交到架构状态(CPU 寄存器或写回内存)。

若发生了分支预测错误,因为分支预测投机的指令最多到达执行阶段,不会提交,所以这种特殊情况就不叫做retirement了。

pipeline slot(流水线槽)

一个流水线槽代表处理一个uOp所需的硬件资源。

TMA分析原理

总体思路大纲:

TMA解决的问题就是如何求得CPU瓶颈。

首先看CPU流水线总体上有多少时间没有真正在处理计算任务(流水线利用率)。

继而观察没有处理计算任务是因为各方面没有协调好导致流水线空转(Stalled),还是虽然没有空转(Non-stalled)但却没有进行实际的计算。

然后针对空转,看看是前端的原因还是后端的原因。然后再具体看是前/后端哪一个具体事件导致的空转。

简化流水线视图

上述流水线视图的虚线划分依据为是否顺序执行。黄色区域表示前端,粉红区域表示后端。

或许下面的图更简洁一些:

在最近的Intel微架构中,流水线的前端每个周期可以分配4个uOps,而后端每个周期可以执行完成4个uOps。

假设对于每个CPU内核,在每个时钟周期上,有四个流水线槽可用。

在任何周期中,流水线槽可能是空闲的,也可能是被用uOp使用的。如果一个槽位在一个时钟周期内是空闲的,这种现象被归于停滞(stall)。

流水线槽的状态(如是否空闲)在分配点(在上图中用星号标记)处获取,这里uOps离开前端并到达后端。

下一步需要对流水线槽进行分类,确定是流水线的前端部分还是后端部分造成了停滞。

Front-End Bound slot: 如果停滞是由于前端无法用uOp填充槽造成的,那么在此周期它将被归类为前端绑定槽(Front-End Bound slot),这意味着性能受到前端绑定类别下的某些瓶颈的限制。

Back-End Bound:如果前端已准备好uOp,但由于后端尚未准备好处理它而因此无法交付它,则空流水线槽将被分类为后端绑定(Back-End Bound)。 后端停滞(backend stalls)通常是由后端耗尽某些资源(例如,负载缓冲区)造成的。

但是,如果前端和后端都停止了,那么插槽将被归类为后端。 这是因为,在这种情况下,修复前端的停滞很可能对应用程序的性能没有帮助。 后端的瓶颈是限制性的,它需要在修复前端的问题前先被移除。

上述内容可以这么想象:

在一个流水线工厂中,一个CPU Core相当于一台流水线机器+一个工人。

一个CPU Core中有n个执行单元,相当于一个工人有n双手。

在每次CPU时钟周期,老板会派发4个任务(uOp)给工人。

工人每次CPU时钟周期也需要完成4个任务(uOp)。

工人完成任务需要资源部件(pipeline slot),所以每次CPU时钟周期流水线机器都会出现4个资源部件(pipeline slot)给工人完成任务用,哪个资源部件(pipeline slot)用于哪个任务(uOp)是老板指定的。

资源部件(pipeline slot)在工人的工作下转化为了成果,当然还有没有转化为成果的现象,我们称这种现象为停滞(stall)。

出现这种现象的原因有:老板的问题(Front-End Bound slot for this cycle),工人的问题(backend stalls)。老板的问题出在没有发出任务与资源部件对应。工人的问题出在工人未能将资源部件(pipeline slot)转化为成果

TMA 指标和计算原理

指标就是占用pipeline slot的百分比(流水线资源利用率)

计算原理看这个博客:Topdown原理

如何判断性能瓶颈?

若超过上述指标范围的则需要注意

优化指导

hotport(热点),所谓热点即是占用CPU时间周期较长的程序/函数/指令/...

可参考此博客

优化后端

大多数未调优的应用程序都是后端瓶颈的。 解决后端问题通常与解决延迟源有关,延迟源会导致执行完成所需的时间超过必要时间。

后端停滞可以再细分为两类:内存瓶颈和内核瓶颈子指标。

内存瓶颈类别中的停滞有与内存子系统相关的原因。 例如,缓存未命中和内存访问可能导致内存瓶颈的停滞。

内核瓶颈停滞是由于在每个周期中对CPU中可用执行单元的使用没有达到最佳状态造成的。槽只有在它们被停止并且没有未完成的内存访问时才被归类为内核瓶颈

大多数后端瓶颈问题都属于内存瓶颈类别。核心瓶颈在后端瓶颈中通常不太常见。

内存瓶颈类别下的大多数指标确定了从L1缓存到内存的内存层次结构的那个级别是瓶颈。一旦后端停止,指标将尝试将负载的停止归因于特定级别的缓存或正在运行的存储。如果热点瓶颈在给定的级别,这意味着它的大部分数据都是从该缓存或内存级别检索的。

优化前端

流水线的前端部分成为应用程序的瓶颈并不常见。 然而,在某些情况下,前端可以在很大程度上造成机器停滞。

提高前端性能通常与代码布局和编译器技术有关。分支代码或占用空间大的代码(代码的footprint大)很可能导致前端停滞

将前端停滞可以再细分为两类:前端延迟和前端带宽。

前端延迟报告一个周期的范围内前端没有处理uOps,而后端已经准备好使用它们的周期。

前端带宽报告处理数量小于4个uOps的周期,这意味着对前端能力的低效率使用。

Bad Speculation类别调优

实践工具

pmu-tools

参考博客

Intel VTune Profiler Performance Analysis Cookbook — Simplified Chinese 官方文档

Top-down Microarchitecture Analysis Method Cookbook 官方文档英文

倚天710性能监控 —— 自顶向下的CPU架构性能瓶颈分析方法-Topdown

C/C++ 性能优化背后的方法论:TMAM

几句话说清楚13:什么是Top-Down性能分析方法

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号