Intel CPU 上使用 pmu-tools 进行 TopDown 分析

2023-05-16


title: Intel CPU 上使用 pmu-tools 进行 TopDown 分析
date: 2021-01-24 18:40
author: gatieme
tags:
- debug
- linux
- todown
categories:
- debug

thumbnail:
blogexcerpt: 这篇文章旨在帮助希望更好地分析其应用程序中性能瓶颈的人们. 有许多现有的方法可以进行性能分析, 但其中没有很多方法既健壮又正式. 而 TOPDOWN 则为大家进行软硬协同分析提供了无限可能. 本文通过 pmu-tools 入手帮助大家进行 TOPDOWN 分析.


CSDNGitHubOSKernelLAB
紫夜阑珊-青伶巷草LDD-LinuxDeviceDriversIntel CPU 上使用 pmu-tools 进行 TopDown 分析

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处, 谢谢合作.

因本人技术水平和知识面有限, 内容如有纰漏或者需要修正的地方, 欢迎大家指正, 鄙人在此谢谢啦


1 Topdown & PMU-TOOLS 简介


1.1 TopDown 简介


程序的执行效率是完全依赖与 CPU 执行的, 软件的性能优化, 除了通用的一些优化外, 更重要的是软硬协同优化, 充分发挥 CPU 的硬件特性. 因此我们软件上的一些性能问题, 可以在 CPU 执行流程中的某一环直观的显现出来. 但是由于 CPU 的复杂性, 普通用户和软件开发人员很难也很少有经历去弄懂 CPU 架构, 更不用谈从 CPU 架构上理解软件上那一块出现的问题.

如果有一套软硬协同的分析方法, 可以帮助用户快速了解/分析/定界/定位 当前应用在 CPU 上的性能瓶颈, 用户就可以针对当前 CPU 有针对性的修改自己的程序, 以充分利用当前的硬件资源.

因此 Intel 提出了一套软硬协同进行性能分析的更正式的方法. 它称为自上而下的微体系结构分析方法(TMAM) (<英特尔®64和IA-32架构优化参考手册> 附录B.1). 在这种方法论中, 我们尝试从高层组件(如前端, 后端, 退休, 分支预测器)开始检测导致执行停滞的原因, 并缩小性能低效的根源.

Intel TOPDOWN-自上而下的微体系结构分析方法

进行 TOPDOWN 分析的过程通过是一个不断迭代优化的过程, 他的通常流程如下

  1. 确定性能问题的类型;
    1.1. 我们可以先从高层次的划分中, 先粗粒度的当前性能问题主要问题是在哪个阶段(类型).
    1.2. 接着从低层次的划分中, 继续明确具体是哪块出的问题.

  2. 使用精确事件 PEBS(X86)/SPE(ARM64) 在代码中找到确切的位置;
    2.1. 如果条件运行, 精确的抓取对应的 PMU 事件, 明确代码中出现问题的原因和位置.

  3. 解决性能问题后, 重新开始 1.
    3.1. 修改代码, 解决性能问题, 然后重新进行 TOPDOWN 分析, 验证修改是否 OK, 看是否还有其他瓶颈或者是否引入其他问题.

1.2 TopDown 资料汇总


Top-down Microarchitecture Analysis Method(TMAM)资料
之前介绍过TMAM的具体内容, 在这里对网络上相关的信息和资料做一个汇总:

  •   国外资料
    

Tuning Applications Using a Top-down Microarchitecture Analysis Method

Top-down Microarchitecture Analysis through Linux perf and toplev tools

A Top-Down method for performance analysis and counters architecture

Performance_Analysis_in_a_Nutshell

Top Down Analysis Never lost with Xeon® perf. counters

How TMA* Addresses Challenges in Modern Servers and Enhancements Coming in IceLake

  •   国内资料
    

几句话说清楚15:Top-Down性能分析方法资料及Toplev使用

让 CPU 黑盒不再黑盒

1.3 PMU-TOOLS 简介


pmu-tools 是 Intel 的 Adni Kleen 开发的帮助用户和开发者在 Intel X86 CPU 下进行 TOPDOWN 分析的开源工具包, 可以定位和分析 CPU Bound 代码的瓶颈, 不能识别其他(Not bound by CPU)代码的瓶颈.

2 PMU-TOOLS 安装


2.1 下载 github 仓库


git clone https://github.com/andikleen/pmu-tools

2.2 下载 PMU 表


pmu-tools 完成的具体工作就是采集 PMU 数据, 并按照微架构既定的公式计算 topdown 数据, 但是不同的微架构和 CPU 所支持的 PMU 事件是不同的, 因此 pmu-tools提供了一套完成的映射表, 标记不同 CPU 所支持的 PMU 事件映射表, 以及 topdown 如何使用这些 PMU 数据去计算, 参见 Intel 01.day perfmon 下载.

pmu-tools 的工具在第一次运行的时会通过 event_download.py 把本机环境的 PMU 映射表自动下载下来, 但是前提是你的机器能正常连接 01.day 的网络. 很抱歉我司内部的服务器都是不行的, 因此 pmu-tools 也提供了手动下载的方式.

因此当我们的环境根本无法连接外部网络的时候, 我们只能通过其他机器下载实际目标环境的事件映射表下载到另一个系统上, 有点交叉编译的意思.

  • 首先获取目标机器的 CPU 型号
printf "GenuineIntel-6-%X\n" $(awk '/model\s+:/ { print $3 ; exit } ' /proc/cpuinfo )

cpu的型号信息是由 vendor_id/cpu_family/model/stepping 等几个标记的.

他其实标记了当前 CPU 是哪个系列那一代的产品, 对应的就是其微架构以及版本信息.

注意我们使用了 %X 按照 16 进制来打印

注意上面的命令显示制定了 vendor_id 等信息, 因为当前服务器端的 CPU 前面基本默认是 GenuineIntel-6 等.

不过如果我们是其他机器, 最好查看下 cpufino 信息确认.

比如我这边机器的 CPU 型号为 :

processor       : 7
vendor_id       : GenuineIntel`
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Gold 6161 CPU @ 2.20GHz
stepping        : 4
microcode       : 0x1

对应的结果就是 GenuineIntel-6-55-4.

我们也可以直接用 -v 打出来 CPU 信息.

$ python ./event_download.py  -v

My CPU GenuineIntel-6-55-4
  • 获取 PMU 映射表

如果你可以链接网络, 那么这个命令就会把你 host 机器上的 PMU 映射表下载下来. 否则你拿到了 CPU 型号, 那么你可以直接显式指定 CPU 型号来获取.

$ python ./event_download.py GenuineIntel-6-55-4

Downloading https://download.01.org/perfmon/mapfile.csv to mapfile.csv
Downloading https://download.01.org/perfmon/SKX/skylakex_core_v1.24.json to GenuineIntel-6-55-4-core.json
Downloading https://download.01.org/perfmon/SKX/skylakex_matrix_v1.24.json to GenuineIntel-6-55-4-offcore.json
Downloading https://download.01.org/perfmon/SKX/skylakex_fp_arith_inst_v1.24.json to GenuineIntel-6-55-4-fp_arith_inst.json
Downloading https://download.01.org/perfmon/SKX/skylakex_uncore_v1.24.json to GenuineIntel-6-55-4-uncore.json
Downloading https://download.01.org/perfmon/SKX/skylakex_uncore_v1.24_experimental.json to GenuineIntel-6-55-4-uncoreexperimental.json
my event list /home/chengjian/.cache/pmu-events/GenuineIntel-6-55-4-core.json

最终 PMU 的映射表文件, 将被保存在 ~/.cache/pmu-events. 将此目录打包后, 放到目标机器上解压即可.

当前我们也可以使用 event_download.py -a 下载所有可用的 PMU 事件映射表. 然后通过如下环境变量, 将 PMU 映射手动指向正确的文件.

export EVENTMAP=~/.cache/pmu-events/GenuineIntel-6-55-4-core.json
export OFFCORE=~/.cache/pmu-events/GenuineIntel-6-55-4-offcore.json
export UNCORE=~/.cache/pmu-events/GenuineIntel-6-55-4-uncore.json

最后两个 offcore/uncore 的设置是可选的. 或者可以将名称设置为 CPU 标识符(GenuineIntel-FAM-MODEL), 这将覆盖当前 CPU.

另一种方法是显式设置目标机器的 PMU 映射文件存储路径( 注意是在相对于它的 pmu-events 目录中).

export XDG_CACHE_DIR=/opt/cache

则将从 /opt/cache/pmu-events 中查找对应的映射文件.

3 PMU-TOOLS 使用


3.1 准备工作


特别需要注意的是, pmu-tools 的大多数工作在使用期间都建议我们禁用 NMI watchdog, 并以 root 身份运行.

因为 X86_64 的 NMI_WATCHDOG 使用了一些 PMU 的寄存器, 同时我们在抓取的时候可能耗时过长, 存在出发 NMI_WATCHDOG 的影响.

Consider disabling nmi watchdog to minimize multiplexing
(echo 0 > /proc/sys/kernel/nmi_watchdog as root)

使用如下命令关闭

sysctl -p 'kernel.nmi_watchdog=0'

OR

echo 0 > /proc/sys/kernel/nmi_watchdog

3.1 toplev


toplev 是一个基于 perfTMAM 方法的应用性能分析工具. 从之前的介绍文章中可以了解到 TMAM 本质上是对 CPU Performance Counter 的整理和加工. 取得 Performance Counter 的读数需要 perf 来协助, 对读数的计算进而明确是 Frondend bound 还是 Backend bound 等等.

在最终计算之前, 你大概需要做三件事:

  1. 明确 CPU 型号, 因为不同的 CPU, 对应的 PMU 也不一样
  2. 读取 TMAM 需要的 perf event 读数
  3. 按 TMAM 规定的算法计算, 具体算法在这个 Excel 表格里

这三步可以自动化地由程序来做. 本质上 toplev 就是在做这件事.

toplev的Github地址: https://github.com/andikleen/pmu-tools

另外补充一下, TMAM作为一种Top-down方法, 它一定是分级的. 通过上一级的结果下钻, 最终定位性能瓶颈. 那么toplev在执行的时候, 也一定是包含这个“等级”概念的.

下面是 toplev 使用方法的资料:

toplev manual

pmu-tools, part II: toplev

基本上都是由 toplev 的开发者自己写的, 可以作为一个 Quick Start Guide.

首先可以进行 L1 级别的检查

$ python toplev.py --core S0-C0 -l1 -v --no-desc taskset -c 0 ./a.out
...
S0-C0    FE             Frontend_Bound:          % Slots          19.2 <
S0-C0    BAD            Bad_Speculation:         % Slots           4.6 <
S0-C0    BE             Backend_Bound:           % Slots           4.1 <
S0-C0    RET            Retiring:                % Slots          72.1 <
S0-C0-T0                MUX:                     %               100.0
S0-C0-T1                MUX:                     %               100.0

接着进行 level2/level3 级别的检查, 最大支持到 level6.

$ python toplev.py --core S0-C0 -l2 -v --no-desc taskset -c 0 ./a.out
$ python toplev.py --core S0-C0 -l3 -v --no-desc taskset -c 0 ./a.out

toplev 工具是基于 perf 等工具进行采样的, 因此多数这些工作支持的行为, toplev 也是支持的.

  • 默认情况下, toplev 同时测量内核和用户代码. 如果只对用户代码感兴趣, 则可以使用 --user 选项. 这往往会减少测量噪声, 因为中断被过滤掉了. 还有一个 --kernel 选项用来测量内核代码.

  • 在具有多个阶段的复杂工作负载上, 测量间隔也是有用的. 这可以用 -I xxxi 选项指定, xxx 是间隔的毫秒数. perf 要求时间间隔至少需要 100ms. toplev 将输出每个间隔的测量值. 这往往会产生大量的数据, 所以绘制输出很有必要.

更多详细信息可以参照 topdev 的 help 帮助文档.

4 参考资料


Top-Down performance analysis methodology


  • 本作品/博文 ( AderStep-紫夜阑珊-青伶巷草 Copyright ©2013-2017 ), 由 成坚(gatieme) 创作.

  • 采用知识共享许可协议知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可. 欢迎转载、使用、重新发布, 但务必保留文章署名成坚gatieme ( 包含链接: http://blog.csdn.net/gatieme ), 不得用于商业目的.

  • 基于本文修改后的作品务必以相同的许可发布. 如有任何疑问, 请与我联系.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Intel CPU 上使用 pmu-tools 进行 TopDown 分析 的相关文章

  • Intel 64架构中CALLF(Far Call)可以有64位地址内存操作数吗?

    在 Intel 32 位架构中 我可以使用 ModR M 字节调用 32 位地址位置 根据英特尔手册 我需要 2 010B 用于操作码扩展 00B 用于 Mod 101B 允许我拥有 32 位位移 如果我想在 64 位架构中进行远调用 以便
  • Java限制资源使用

    有没有办法限制java使用的核心数量 同样 是否有可能限制该核心的使用量 您可以在 Linux 上使用任务集 您还可以降低进程的优先级 但除非 CPU 繁忙 否则进程将获得尽可能多的 CPU 我有一个将线程专用于核心的库 称为 Java T
  • 在 Skylake 上展开 1 周期循环会使性能降低 25%。 uops调度问题?

    TL DR我有一个循环需要 1 个周期才能在 Skylake 上执行 它执行 3 次加法 1 次增量 跳转 当我将其展开超过 2 次 无论多少次 时 我的程序运行速度会慢 25 左右 这可能与对齐有关 但我不清楚是什么 编辑 这个问题曾经询
  • C linux相当于windows QueryPerformanceCounter

    Linux 中是否有等效的 C 函数用于读取 CPU 计数器及其频率 我正在寻找类似于 QueryPerformanceCounter 函数的东西 该函数读取现代 CPU 中的 64 位计数器 clock gettime 2 http li
  • 多处理和并行处理之间的比较

    有人能告诉我多处理和并行处理之间的确切区别吗 我有点困惑 感谢您的帮助 多重处理 多重处理是使用两个或多个中央处理单元 单个计算机系统中的 CPU 该术语还指 系统支持多个处理器和 或的能力 在他们之间分配任务的能力 并行处理 在计算机中
  • 使用 C# 识别 CPU 架构类型

    我想检查用户运行的是哪个CPU架构 是吗 i386 或 X64 或 AMD64 我想用 C 来做 我知道我可以尝试 WMI 或注册表 除了这两种还有其他办法吗 我的项目目标是 NET 2 0 让我来到这里的是检查 32 位与 64 位操作系
  • GPU 的延迟是多少?

    我可以找到 CPU 核心与其缓存 主内存等之间的 CPU 周期延迟 但似乎很难找到有关现代 GPU 的类似信息 有谁知道 GPU 的延迟 特别是现代 nvidia GPU GF110 或更高版本 与其内存之间的延迟 谢谢 GPU 内存确实具
  • 哪个更快:x<<1 或 x<<10?

    我不想优化任何东西 我发誓 我只是出于好奇而想问这个问题 我知道在大多数硬件上都有位移位的汇编命令 例如shl shr 这是一个单一命令 但移位多少位 从纳秒角度或从 CPU 角度角度 是否重要 换句话说 以下任一选项在任何 CPU 上都更
  • 如何让Java使用机器上的所有CPU资源?

    我有时用 Java 编写代码 我注意到有时它在多核机器上使用超过 100 的 CPU 我现在正在一台具有 33 个 CPU 亚马逊的 EC2 的多核机器上运行一些代码 我想让我的 Java 进程使用所有可用的 CPU 这样它将具有非常高的机
  • x86_64:IMUL 比 2x SHL + 2x ADD 更快吗?

    当查看 Visual Studio 2015U2 生成的程序集时 O2 发布 模式我看到这段 手工优化 的 C 代码被翻译回乘法 int64 t calc int64 t a return a lt lt 6 a lt lt 16 a 集会
  • 存储缓冲区是否保存现代 x86 上的物理地址或虚拟地址?

    现代 Intel 和 AMD 芯片大存储缓冲区 https stackoverflow com a 54880249 149138在提交到 L1 缓存之前缓冲存储 从概念上讲 这些条目保存存储数据和存储地址 对于地址部分 这些缓冲区条目是否
  • 核心和处理器之间的区别

    核心和处理器有什么区别 我已经在谷歌上寻找过它 但我只得到了多核和多处理器的定义 这不是我正在寻找的 核心通常是 CPU 的基本计算单元 它可以运行单个程序上下文 如果支持硬件线程 例如 Intel CPU 上的超线程 则可以运行多个程序上
  • 单核上的多线程有什么意义?

    我最近一直在研究 Linux 内核 并回顾了大学操作系统课程的时代 就像那时一样 我正在玩线程之类的东西 一直以来我一直假设线程是自动在多个核心上同时运行但我最近发现您实际上必须显式编写代码来处理多个核心 那么单核上的多线程有什么意义呢 我
  • k8s hpa无法获取cpu信息[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我设置了 hpa 使用命令 sudo kubectl autoscale deployment e7 build 64 cpu perce
  • java中获取某些进程的cpu使用率的正确命令行是什么

    给定进程 ID 在 Java 中从进程获取当前 cpu 使用情况的正确命令是什么 命令 typeperf Memory Available bytes processor total process time 不适用于特定进程 并且任何第
  • Django 开发服务器 CPU 密集型 - 如何分析?

    我注意到本地 windows7 机器上的 django 开发服务器 版本 1 1 1 正在使用大量 CPU 根据任务管理器的 python exe 条目 约为 30 即使处于空闲状态 即没有请求到来进 出 是否有一种既定的方法来分析可能造成
  • 将 CPU 频率指定为 Linux 启动时的内核 CMD_LINE 参数?

    我将笔记本电脑的i5 CPU更换为i7 CPU 这样它可以运行得更快 但由于i7的功率更大 温度也比以前更高 所以我的笔记本经常死机 所以 我使用cpupower来指定CPU的最大频率 它起作用了 现在 我的问题是 有没有办法在启动时将CP
  • 什么是微编码指令?

    我看过很多参考微编码指令的文献 这些是什么以及为什么使用它们 CPU 读取机器代码并将其解码为内部控制信号 将正确的数据发送到正确的执行单元 大多数指令映射到一个内部操作 并且可以直接解码 例如 在 x86 上 add eax edx只是将
  • 在 x86 Intel VT-X 非根模式下,是否可以在每个指令边界传递中断?

    除了不将中断传送到虚拟处理器的某些正常指定条件 cli if 0 等 之外 客户机中的所有指令实际上都是可中断的吗 也就是说 当传入的硬件中断先传递给 LAPIC 然后传递给处理器时 据说会发生一些内部魔法 将其转换为虚拟中断给来宾 使用虚
  • 就 size_t 而言,“目标平台上最大可能对象的大小”是多少

    我正在阅读有关的文章size t在 C C 中http web archive org web 20081006073410 http www embedded com columns programmingpointers 2009001

随机推荐