Post

【笔记】AMD IBS 使用笔记

实验需求使用 perf_event_open 调用 AMD IBS 实现对于线程访存的监控,因此开始了解一下 IBS。

AMD IBS(Instruction-Based Sampling,基于指令采样)是 AMD 处理器中一项硬件级性能分析技术,用于监控和记录处理器执行的指令流,为开发者和系统管理员提供细粒度的性能洞察。

IBS 文档:https://www.amd.com/content/dam/amd/en/documents/archived-tech-docs/white-papers/AMD_IBS_paper_EN.pdf (没什么有用的内容)

IBS 采样结构体内容详见:https://www.weigao.cc/architecture/ibs.html#_1-ibs

调用方式

perf_event_open() + raw IBS

Linux 集成的 perf 子系统支持 IBS 事件,可以使用 perf_event_open() syscall 直接采集 ibs_op 类型事件,然后 mmap 一个 ring buffer 直接读取采样样本。

注意 mmap 的 buffer 大小必须是 $ 1 + 2^n $ 个 page,否则会 failed。

以及一定要先检查内核编译时是否支持 ibs,如果不支持 ibs ,perf_event_open() 不会读取到任何内容也不会报错,需要更换一个支持 ibs 的内核。这导致我浪费了两天时间排查 raw data 的解码问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <linux/perf_event.h>
#include <asm/unistd.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

long page_size = sysconf(_SC_PAGESIZE);
int mmap_pages = 9;  // ring buffer 大小必须是 1+2^n 页
size_t mmap_size = page_size * mmap_pages;

int fd;
struct perf_event_attr attr;

void init_ibs_perf() {
    memset(&attr, 0, sizeof(struct perf_event_attr));
    attr.type = PERF_TYPE_RAW;  // 对于 IBS,用 RAW 类型
    attr.size = sizeof(struct perf_event_attr);
    attr.config = 0x1;  // 0x1 = IBS_OP(ibs_op 控制器)
    attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_RAW;
    attr.sample_period = 1000000;
    attr.exclude_kernel = 0;  // 监控内核空间
    attr.exclude_user = 0;    // 监控用户空间
    attr.disabled = 0;
    attr.read_format = 0;
}

void read_ibs_perf() {
    fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
    if (fd < 0) {
        perror("perf_event_open failed");
        return;
    }

    void* buf = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (buf == MAP_FAILED) {
        perror("mmap failed");
        close(fd);
        fd = -1;
        return;
    }

    printf("成功打开IBS性能监控,开始读取数据...\n");
    printf_ibs_perf(fd, buf, mmap_size);

    // 清理mmap
    munmap(buf, mmap_size);
}

MSR 寄存器直接访问

可以直接访问 IBS 的寄存器来启用采样读取数据。

名称编号说明
IBS_OP_CTL0xC0011033控制器寄存器
IBS_OP_DATA30xC001103B包含 DcMissLat 等信息
IBS_OP_RIP0xC0011035指令地址
IBS_OP_DATA0xC0011036执行状态

可以通过 rdmsr_on_cpu() + 定时中断轮询方式采集,但这种方法依赖内核权限。

AMD IBS Toolkit

AMD 编写了针对应用场景的 IBS Toolkit,可以尝试直接使用,我没有深入研究。

https://github.com/jlgreathouse/AMD_IBS_Toolkit

This post is licensed under CC BY 4.0 by the author.

© sazikk. Some rights reserved.

Total views. 您是第个访问者

Using the Chirpy theme for Jekyll.