PERF_TYPE_HARDWARE 和 PERF_TYPE_HW_CACHE 并发监控

标签 perf multiplexing intel-pmu

我正在 perf_event_open 之上进行自定义实现系统调用。

该实现旨在支持各种PERF_TYPE_HARDWARE , PERF_TYPE_SOFTWAREPERF_TYPE_HW_CACHE事件 任何内核上的特定线程 .

在英特尔® 64 位和 IA-32 架构软件开发人员手册第 3B 卷中,我看到以下用于测试 CPU (Kaby Lake) 的内容:

enter image description here

到目前为止,我的理解是,可以(理论上)无限监控 PERF_TYPE_SOFTWARE事件并发但有限(无多路复用)PERF_TYPE_HARDWAREPERF_TYPE_HW_CACHE事件同时发生,因为每个事件都是由 CPU 的 PMU 计数器的有限数量(如上面的手册中所见)测量的。

因此,对于启用超线程的四核 Kaby Lake CPU,我假设最多 4 PERF_TYPE_HARDWARE/PERF_TYPE_HW_CACHE可以同时监视事件(如果仅使用 4 个线程,则最多可监视 8 个)。

尝试上述假设后,我发现虽然我可以成功监控多达 4 个 PERF_TYPE_HARDWARE事件(对于 8 个线程)PERF_TYPE_HW_CACHE 不是这种情况最多只能同时监视 2 个事件的事件!

我还尝试仅使用 4 个线程,但同时监控的“PERF_TYPE_HARDWARE”事件的上限仍然为 4。超线程 也是如此。已禁用 !

有人可能会问:为什么需要避免多路复用。首先,实现需要尽可能准确,避免多路复用的潜在盲点,其次,当超过“上限”时,所有事件值都为 0...
PERF_TYPE_HW_CACHE我的目标事件是:

CACHE_LLC_READ(PERF_HW_CACHE_TYPE_ID.PERF_COUNT_HW_CACHE_LL.value  | PERF_HW_CACHE_OP_ID.PERF_COUNT_HW_CACHE_OP_READ.value << 8 | PERF_HW_CACHE_OP_RESULT_ID.PERF_COUNT_HW_CACHE_RESULT_ACCESS.value << 16),
CACHE_LLC_WRITE(PERF_HW_CACHE_TYPE_ID.PERF_COUNT_HW_CACHE_LL.value  | PERF_HW_CACHE_OP_ID.PERF_COUNT_HW_CACHE_OP_WRITE.value << 8 | PERF_HW_CACHE_OP_RESULT_ID.PERF_COUNT_HW_CACHE_RESULT_ACCESS.value << 16),
CACHE_LLC_READ_MISS(PERF_HW_CACHE_TYPE_ID.PERF_COUNT_HW_CACHE_LL.value  | PERF_HW_CACHE_OP_ID.PERF_COUNT_HW_CACHE_OP_READ.value << 8 | PERF_HW_CACHE_OP_RESULT_ID.PERF_COUNT_HW_CACHE_RESULT_MISS.value << 16),
CACHE_LLC_WRITE_MISS(PERF_HW_CACHE_TYPE_ID.PERF_COUNT_HW_CACHE_LL.value  | PERF_HW_CACHE_OP_ID.PERF_COUNT_HW_CACHE_OP_WRITE.value << 8 | PERF_HW_CACHE_OP_RESULT_ID.PERF_COUNT_HW_CACHE_RESULT_MISS.value << 16),

所有这些都使用提供的公式实现:
(perf_hw_cache_id) | (perf_hw_cache_op_id << 8) |
(perf_hw_cache_op_result_id << 16)

并且作为一个群体被操纵(第一个是组长等)。

所以,我的问题如下:
  • PMU 的哪些计数器用于 PERF_TYPE_HARDWARE而对于 PERF_TYPE_HW_CACHE事件以及在哪里可以找到这些信息?
  • PERF_TYPE_HARDWARE有什么区别预定义事件(例如 PERF_COUNT_HW_CACHE_MISSES )和 PERF_TYPE_HW_CACHE事件?
  • 关于如何在不复用所有列出的情况下进行监控的任何建议 PERF_TYPE_HW_CACHE事件?
  • 关于如何在不复用多达 8 个的情况下进行监控的任何建议 PERF_TYPE_HARDWARE或/和 PERF_TYPE_HW_CACHE事件?

  • 提前致谢!

    最佳答案

  • PERF_TYPE_HARDWAREPERF_TYPE_HW_CACHE事件被映射到性能监控中涉及的两组寄存器。第一组 MSR 被称为 IA32_PERFEVTSELx其中 x 可以在 0 到 N-1 之间变化,N 是可用的通用计数器总数。 PERFEVTSEL是“性能事件选择”的缩写,它们指定了实现事件计数的各种条件。第二组 MSR 称为 IA32_PMCx ,其中 x 的变化与 PERFEVTSEL 类似.这些 PMC 寄存器存储性能监控事件的计数。每个PERFEVTSEL寄存器与相应的 PMC 配对登记。

  • 映射发生如下 -

    在内核的体系结构特定部分初始化时,注册了一个用于测量硬件特定事件的 pmu here带类型 PERF_TYPE_RAW .全部 PERF_TYPE_HARDWAREPERF_TYPE_HW_CACHE事件映射到 PERF_TYPE_RAW事件来识别 pmu,可以看出 here .
    if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE)
            type = PERF_TYPE_RAW;
    

    相同架构特定的初始化负责设置上述每组性能监控事件寄存器的第一个/基址寄存器的地址,here
        .eventsel       = MSR_ARCH_PERFMON_EVENTSEL0,
        .perfctr        = MSR_ARCH_PERFMON_PERFCTR0,
    
    event_init特定于 PMU 识别的功能,负责设置和“保留”两组性能监控寄存器,以及检查事件约束等,here .预订发生here .
    for (i = 0; i < x86_pmu.num_counters; i++) {
            if (!reserve_perfctr_nmi(x86_pmu_event_addr(i)))
                goto perfctr_fail;
        }
    
        for (i = 0; i < x86_pmu.num_counters; i++) {
            if (!reserve_evntsel_nmi(x86_pmu_config_addr(i)))
                goto eventsel_fail;
        }
    

    num_counters = 由 CPUID 标识的通用计数器的数量操作说明。

    除此之外,还有几个额外的 registers监控非核心事件(例如,LLC 缓存特定事件)。

    在架构性能监控的更高版本中,一些硬件事件是在固定用途寄存器的帮助下测量的,如 here 所示。 .这些是固定用途的 registers ——
    #define MSR_ARCH_PERFMON_FIXED_CTR0 0x309
    #define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a
    #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b
    
  • PERF_TYPE_HARDWARE预定义 events都是建筑 性能监控事件。这些事件是体系结构的,因为每个体系结构性能事件的行为预计在支持该事件的所有处理器上都是一致的。所有的PERF_TYPE_HW_CACHE事件是非建筑 ,这意味着它们是特定于模型的,并且可能因处理器系列而异。
  • 对于我拥有的 Intel Kaby Lake 机器,总共 20 PERF_TYPE_HW_CACHE事件是预先定义的。事件约束involved ,确保可用的 3 个固定功能计数器映射到 3 PERF_TYPE_HARDWARE建筑事件。每个固定功能计数器只能测量一个事件,因此我们可以将它们丢弃以进行分析。另一个限制是只能同时测量两个针对 LLC 缓存的事件,因为只有两个 OFFCORE RESPONSE。寄存器。另外,nmi-watchdog可以将事件固定到通用计数器系列中的另一个计数器。如果nmi-watchdog被禁用,我们剩下 4 个通用计数器。

  • 鉴于所涉及的限制以及可用计数器的数量有限,如果同时测量所有 20 个硬件缓存事件,则无法避免多路复用。一些测量所有事件而不引起多路复用及其错误的解决方法是 -

    3.1.群所有PERF_TYPE_HW_CACHE事件分成 4 个一组,这样所有 4 个事件都可以同时在 4 个通用计数器中的每一个上进行调度。确保一个组中的 LLC 缓存事件不超过 2 个。运行相同的配置文件并分别获取每个组的计数。

    3.2.如果所有 PERF_TYPE_HW_CACHE同时监控事件,则可以通过减小 perf_event_mux_interval_ms 的值来减少多路复用的一些错误。 .它可以通过名为 /sys/devices/cpu/perf_event_mux_interval_ms 的 sysfs 条目进行配置。 .这个值不能降低到一个点以上,可以看出here .
  • 监控多达 8 个硬件或硬件缓存事件需要禁用超线程。请注意,有关可用通用计数器数量的信息是使用 CPUID 检索的。通过 early_initcall 在内核启动的体系结构初始化部分设置指令和此类计数器的数量。功能。这个可以看here .初始化完成后,内核知道只有 4 个计数器可用,以后超线程功能的任何更改都没有任何区别。
  • 关于PERF_TYPE_HARDWARE 和 PERF_TYPE_HW_CACHE 并发监控,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61879227/

    相关文章:

    node.js - 使用 perf_events 的 nodejs/v8 火焰图中的未知事件

    linux - 如何分析perf sched脚本和perf sched延迟?

    java - 使用 Netty 用很少的线程发出大量的 http GET 请求

    FFMPEG 如何将 MJPEG 编码数据复用到 mp4 或 avi 容器 c++

    c - 分析C程序函数的缓存命中率

    assembly - LSD 能否从检测到的循环的下一次迭代中发出 uOP?

    memory - 计算对内存的读写访问

    http - 将服务器发送的事件与 HTTP2 一起使用时是否仍然存在实际的 6 个连接限制?

    c - 使用 wrmsrl 和 rdmsrl 读取 PMU 计数器

    linux - 在 Linux 上估算任​​务的 WCET