21.1 PERFORMANCE MONITORING OVERVIEW

  • 从Intel Core Solo和Intel Core Duo处理器开始,有两类性能监视功能。第一个类支持使用计数或基于中断的事件抽样来监视性能的事件。这些事件是非体系结构的,并且因处理器模型的不同而不同。它们与奔腾M处理器中的处理器类似。这些非体系结构性能监视事件是特定于微体系结构的,可能会随着增强而改变。
  • 给定微体系结构的非体系结构事件不能使用CPUID枚举;可以在https://perfmon-events.intel.com/或https://github.com/intel/perfmon/上找到它们。

21.2ARCHITECTURAL PERFORMANCE MONITORING

  • 当性能监视事件跨微体系结构表现一致时,它们就是体系结构的。

  • CPUID.0AH叶片是Intel处理器提供的一种查询指令,可以告诉开发者处理器支持哪些架构性能监控的功能。

    版本ID:处理器的性能监控有不同的“级别”或“版本”。版本ID为1表示支持基本的性能监控(比如监视基本的硬件事件);版本ID为2则表示支持更多高级事件和监控能力。

21.2.1 Architectural Performance Monitoring Version 1

  • 性能监控选择寄存器和计数器在以下方面是架构性的:
    • IA32_PERFEVTSELx的位字段布局在微架构中是一致的。如果在架构性能监控(版本1)的初始实现之后引入非零写入字段,则该字段不受支持,则会导致#GP。
    • IA32_PERFEVTSELx MSR的数量在微架构中保持相同。
    • IA32_PMC MSR的数量在微架构中保持相同。
    • 每个逻辑处理器都有自己的一组IA32_PERFEVTSELx和IA32_PMCx MSR。共享处理器内核的逻辑处理器之间不共享配置工具和计数器。
    • 逻辑处理器中软件可用的性能监视计数器的数量(每个IA32_PERFEVTSELx MSR与对应的IA32_PMCx MSR配对)。
    • 每个IA32_PMCx中支持的比特数。
    • 逻辑处理器中支持的架构性能监视事件的数量

21.2.2Architectural Performance Monitoring Version 2

  • 固定功能性能计数器(PMC):提供三个专用计数器(IA32_FIXED_CTR0IA32_FIXED_CTR2),每个计数器用于监控特定的体系结构事件,且配置时不需要使用 UMASK,简化了设置。
  • 简化事件编程:引入了三个控制寄存器(IA32_PERF_GLOBAL_CTRLIA32_PERF_GLOBAL_STATUSIA32_PERF_GLOBAL_OVF_CTRL),允许软件更方便地启用、禁用和查询计数器状态,以及处理溢出。
  • PMI(性能监控中断)开销降低:通过 IA32_DEBUGCTL 中的特定位来减少中断开销,这样可以在不影响系统性能的情况下收集性能数据。

21.2.3Architectural Performance Monitoring Version 3

  • 架构性能监控版本3(APM v3)增强了跨多线程事件的计数支持,通过AnyThread模式和新的控制寄存器,进一步简化了在多逻辑处理器场景下的性能计数配置和管理。这使得开发者能够在高并发环境下更高效地监控系统性能,同时简化了配置和溢出检测

21.2.4Architectural Performance Monitoring Version 4

PMI(性能监控中断)处理的改进:版本4引入了改进的PMI处理机制,使用IA32_DEBUGCTL.Freeze_LBRs_On_PMIFreeze_PerfMon_On_PMI接口来管理性能监控中断,以替代传统的冻结行为。这一改进旨在降低PMI带来的性能开销,提高性能数据的准确性。

IA32_PERF_GLOBAL_STATUS的新标志位

  • LBR_FRZ(位58):指示是否冻结LBR(最后分支记录)堆栈。
  • CTR_FRZ(位59):指示是否冻结所有性能计数器。这些标志位支持在产生PMI时冻结特定数据,帮助剔除不必要的数据干扰,从而提升性能分析的准确性。

状态复位与设置

  • 版本4引入了IA32_PERF_GLOBAL_STATUS_RESETIA32_PERF_GLOBAL_STATUS_SET寄存器,用于精细控制性能状态位的复位和设置,替代之前的IA32_PERF_GLOBAL_OVF_CTRL接口,使得软件能够独立清除或设置特定的状态位,提高了对监控状态的管理灵活性。

共享协议的支持

  • IA32_PERF_GLOBAL_INUSE寄存器支持不同软件代理之间的资源共享协议。此寄存器提供每个性能计数器的”使用中”状态位,帮助不同的性能监控代理协作分配监控资源,防止冲突。这种机制允许多个服务同时有效地使用处理器的性能监控功能。

ToPA与SGX相关的支持

  • 引入了TraceToPAPMI(位55)和ASCI(位60)标志,前者用于检测使用ToPA(表面下预留的缓冲区)方案的Intel处理器跟踪的PMI情况,后者用于检测数据是否因SGX(软件保护扩展)操作而变更。这些标志位可以帮助区分和管理不同的监控场景,特别是涉及到Intel安全扩展SGX的情况。

21.2.5 Architectural Performance Monitoring Version 6

  1. 性能监控 MSR 别名 (Performance Monitoring MSR Aliasing)
  • 新地址范围:版本6新增了一个位于 19xxH 地址范围的 MSR 区域,用于扩展通用计数器和固定功能计数器的数量,便于更大规模的性能数据采集。
  • 别名机制:支持在新旧地址范围中访问某些计数器(通过IA32_PMC_GPn_CTR访问通用计数器,IA32_PMC_FXm_CTR访问固定功能计数器)。但是,一些新定义的计数器只在新地址范围中可用,尤其是那些仅在 CPUID 叶 23H(EAX=23H, ECX=01H)中枚举的计数器。
  • MSR 地址计算:通过特定公式计算 GP 和 FX 计数器的 MSR 地址,例如通用计数器的地址计算为 1900H + 4 * n
  1. Unit Mask 2(UMASK2)
  • 版本6引入了新的

    Unit Mask 2

    字段,用于进一步限定性能事件的检测条件。UMASK2 位置在位 40 到 47,如果 CPUID.(EAX=23H, ECX=0H)

    bit 0

    指示支持 UMASK2,则可用。

  • UMASK2 与 UMASK 搭配使用:该字段可以与原有的 UMASK 字段结合使用,以提供更加细致的条件监控。

  1. Equal 标志(Equal Flag, EQ)
  • EQ 标志

    :当 EQ 标志和 INV 标志的组合不同,可以实现不同的比较条件,以便确定特定事件的发生频率。EQ 位在位 36,仅当 CPUID.(EAX=23H, ECX=0H)

    bit 1

    显示支持时可用。

  • 工作方式

    • EQ 设定且 INV 未设定:当事件计数等于设定的Counter Mask值(CMask)时条件满足。
    • EQ 和 INV 同时设定:当事件计数小于CMask值并且非零时条件满足。

21.2.7Pre-defined Architectural Performance Events

  • 预定义性能事件在支持体系结构性能监控的处理器上可以被统计,具体的支持情况可通过CPUID指令查询。在不同处理器微架构中,同一事件的行为保持一致,但在某些微小的实现细节上可能会有所差异。

  • 这里的表格只有12种

查询

1
cpuid -r | grep -A3 "0x0000000a"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdint.h>

void cpuid(uint32_t code, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) {
asm volatile("cpuid"
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
: "a" (code));
}

int main() {
uint32_t eax, ebx, ecx, edx;
cpuid(0x0A, &eax, &ebx, &ecx, &edx);

int num_arch_events = (eax >> 24) & 0xFF;
int unsupported_events = ebx;

printf("支持的体系结构性能事件数量: %d\n", num_arch_events);
printf("不支持的事件位掩码: 0x%x\n", unsupported_events);

return 0;
}

21.2.8Full-Width Writes to Performance Counter Registers

全宽写入能力

  • 支持全宽写入的处理器会在 IA32_PERF_CAPABILITIES[13] 设置为 1,标志位名称为 FW_WRITE
  • 如果 FW_WRITE(第13位)为1,则说明该处理器支持向性能计数器进行全宽写入。

别名寄存器的存在

  • 当处理器支持全宽写入时,每个 IA32_PMCi 计数器(即 IA32_PMC0IA32_PMC1 等)会有一个对应的别名地址,从 4C1H 开始。例如,第一个别名地址为 IA32_A_PMC0
  • 通过这些别名地址,可以实现64位宽度的计数器写入。

计数器的宽度定义

  • 计数器的位宽通过 CPUID.0AH:EAX[23:16] 指定。
  • 这个值表示处理器的 PMC 计数器实际支持的宽度。对于 64 位性能监控计数器,这个宽度通常是 48 位或更小。

写入操作机制

  • WRMSR 指令用于向 IA32_A_PMCi 寄存器写入64位值(通过 EDX:EAX 指定)。

  • 写入操作的详细规则:

    • COUNTERWIDTH 表示性能监控计数器的实际宽度。

    • IA32_PMCi
      

      将会通过下列方式更新:

      • 高位:IA32_PMCi[COUNTERWIDTH-1:32] 会被 EDX[COUNTERWIDTH-33:0] 的内容更新。
      • 低位:IA32_PMCi[31:0] 会被 EAX[31:0] 的内容更新。
  • 注意:EDX[63:COUNTERWIDTH] 这些位是保留位,通常为0。

21.2.9Scalable Enumeration Architecture

  1. ArchPerfmonExt 扩展枚举
  • CPUID 23H 扩展:通过 CPUID 指令的 23H 叶(leaf 23H),为性能监控单元(PMU)的架构特性提供了更全面的枚举方法。它引入了一种“真视图”(true-view)机制,可以针对每个逻辑处理器(logical processor)查看实际支持的PMU功能,而不仅是所有逻辑处理器的公共集。
  • CPUID 0AH 与 23H 的对比CPUID 0AH 叶报告了所有逻辑处理器的共有特性,但 23H 叶则展示了每个逻辑处理器的特定支持,使得在多核心环境中能够更精准地确定每个逻辑处理器的性能监控能力。
  1. CPUID 子叶机制(Sub-Leafing)
  • 23H 叶使用 子叶机制,通过不同的子叶,细分不同的PMU功能。CPUID.(EAX=23H, ECX=0H):EAX 通过一个位图,标识出各子叶的支持情况。这个机制便于扩展,将来可以添加新的 PMU 特性,而无需修改已有的基础架构。
  1. 针对逻辑处理器的报告
  • 23H 叶提供每个逻辑处理器的 PMU 支持情况,这意味着在运行 CPUID 23H 时,每个逻辑处理器上可能会得到不同的支持信息。因此,软件在每个逻辑处理器上都需要单独读取 CPUID 23H 以获得准确的 PMU 支持情况。
  1. 通用计数器位图
  • CPUID.(EAX=23H, ECX=01H):EAX 提供了通用计数器的可用性位图,相比 CPUID 0AH 中仅报告总数,这个位图能更精细地描述每个计数器的实际可用性。
  • 虚拟化环境的支持:允许虚拟机监控器(VMM)为自己保留低索引计数器,将高索引计数器暴露给虚拟机。
  1. 固定功能计数器位图
  • CPUID.(EAX=23H, ECX=01H):EBX 提供了固定功能计数器的可用性位图,使得软件能够针对每个逻辑处理器,查看哪些固定功能计数器可用。
  1. 架构性能监控事件位图
  • CPUID.(EAX=23H, ECX=03H):EAX 提供了每个逻辑处理器上的架构性能监控事件的位图,展示了可用的事件类型。相对地,CPUID.0AH:EBX 提供了所有逻辑处理器的最大公共事件集位图,用于标识每个事件在所有逻辑处理器上的一致性。
  1. 每周期 TMA 槽位
  • CPUID.(EAX=23H, ECX=0H):ECX[7:0] 提供了每周期的 TMA(Top-Down Microarchitecture Analysis)槽位数,用于测量微架构性能。这是一个“真视图”报告,也就是按逻辑处理器查看结果。在一些逻辑处理器上,这个值可能会为 0,提示可以采用其他方法(如可编程事件或固定计数器)来理解性能状况。

21.3PERFORMANCE MONITORING (INTEL® CORE™ PROCESSORS AND INTEL® XEON® PROCESSORS)

21.3.1Performance Monitoring for Processors Based on Nehalem Microarchitecture

  1. 架构性能监控(Architectural Performance Monitoring)
  • 版本 ID:Intel Core i7处理器家族的架构性能监控版本 ID 为3。
  • 计数器:在处理器核心中,提供了4个通用用途性能计数器(IA32_PMC0IA32_PMC3)和3个固定功能性能计数器(IA32_FIXED_CTR0IA32_FIXED_CTR2),用于监控指定的硬件事件(例如指令数、周期数等)。
  1. 非架构性能监控(Non-Architectural Performance Monitoring)
  • 配置寄存器:使用 IA32_PERFEVTSELx 寄存器(即性能事件选择寄存器)来配置非架构性能监控事件,这些事件可记录到通用用途性能计数器中。

  • 事件列表:这些非架构事件的详细列表可以在 Intel Performance Monitoring Events 网站上找到。

  • 事件分类

    :非架构性能监控事件可分为两类:

    • 处理器核心事件:监控处理器核心中的微架构状态,例如条件检测、核心和芯片其他模块间的交互等。
    • Uncore事件:Uncore模块是指处理器物理封装中共享的子系统(如L3缓存、内存控制器等),它支持额外的性能监控功能,专用于Uncore特定的事件监控。
  1. 线程限定支持
  • 线程限定位:通过IA32_PERFEVTSELx寄存器的第21位,可以限定性能监控事件是否在单线程环境中有效。
  1. 性能监控状态寄存器(IA32_PERF_GLOBAL_STATUS
  • 计数器溢出指示IA32_PERF_GLOBAL_STATUS MSR寄存器用于指示各性能计数器的溢出状态(OVF_PCx 和 OVF_FCx)。

  • 各字段描述

    • OVF_PCx:指示不同通用性能计数器的溢出状态。例如,OVF_PC0OVF_PC7 分别对应的性能计数器 IA32_PMC0IA32_PMC7 的溢出状态(如果有超过4个计数器)。
    • OVF_FCx:指示固定功能性能计数器的溢出状态(OVF_FC0OVF_FC2)。
  1. 特性及应用
  • 通过 CPUID 指令,软件可以获取性能监控计数器的数量信息,便于在多处理器系统中判断各线程、计数器的性能监控特性。
  • 软件能够通过这些寄存器和溢出指示信息,动态调整监控配置和溢出事件处理策略,以优化多线程性能调优。

21.3.1.1.1

  1. PEBS (Processor Event Based Sampling) 概述
  • PEBS 是一种高级性能监控功能,允许处理器记录引发溢出的指令和当前的机器状态(寄存器值、地址等),使得性能事件更具精确性。PEBS 仅支持部分性能事件(非架构性能事件),适用于更精确的性能分析场景。
  1. PEBS 启用和控制
  • PEBS 功能的支持和配置通过寄存器 IA32_MISC_ENABLE 来检测。MSR 寄存器 IA32_PEBS_ENABLE 用于启用 PEBS 功能,通过特定位设置来决定哪个性能计数器(IA32_PMCx)的溢出会触发 PEBS 记录的捕获。
  • PEBS 记录扩展支持记录延迟信息,每个计数器在溢出后可以写入一个 PEBS 记录并获取延迟值(如核心周期数)。
  1. PEBS 记录结构
  • PEBS 记录的格式包括寄存器值、指令指针(RIP)、溢出状态以及其他数据地址和延迟信息。具体记录格式如表格所示(每个字段 64 位长),例如:
    • R/EFLAGSR/EIPR/EAX 等寄存器的值;
    • 数据的线性地址(Data Linear Address);
    • 数据源编码(Data Source Encoding);
    • 延迟值(Latency value)。
  • IA32_PERF_GLOBAL_STATUS 寄存器记录了发生溢出的计数器,便于确定触发的事件。
  1. PEBS 缓冲区管理
  • PEBS 的记录是写入由软件指定的内存缓冲区,缓冲区管理结构由 IA32_DS_AREA 寄存器定义。缓冲区的关键字段如下:
    • PEBS Buffer Base:PEBS 缓冲区的起始地址。
    • PEBS Index:下一个 PEBS 记录的写入位置。
    • PEBS Absolute Maximum:PEBS 缓冲区的最大长度,处理器不会写入超出此值。
    • PEBS Interrupt Threshold:用于生成性能中断的阈值,表示缓冲区几乎满时,处理器会发出通知中断。
  • PEBS CounterX Reset:可以重置计数器的溢出条件,以使 PEBS 捕获足够的记录。
  1. 性能中断优先级
  • PEBS 中断和性能监控中断的优先级根据计数器的编号决定。PEBS 通过首次溢出事件后触发“助力”(assist)记录操作,在生成 PEBS 记录后才会处理性能中断。
  • 不同计数器溢出同时发生时,优先级高的计数器先被处理(IA32_PMC0 优先于其他计数器)。对于固定计数器和一般性能计数器,通常优先处理一般性能计数器。
  1. PEBS 编程注意事项
  • PEBS 仅在性能事件选择寄存器 IA32_PERFEVTSELx 中的字段(如 AnyThread、Edge、Invert、CMask)全部为零时有效。
  • 系统软件需要在内存中预留非分页的缓冲区,避免 PEBS 缓冲区在记录时产生缺页错误、VM 退出等问题。此外,VMM 可能需要通过 EPT(扩展页表)映射访客的物理内存为可读写。
  1. PEBS 与性能监控的结合
  • PEBS 中断通常在 PEBS “助力”之后触发,当 PEBS 达到阈值时生成中断,处理完成后才会继续处理性能计数器的溢出中断。如果发生多重溢出,软件需检查核心和非核心的状态寄存器以确定中断来源。

之后粗略的看了一遍,大多讲的都是每个微架构的监控器/监控工具的架构、性能和使用

暂无需求