系统范围的分析器(例如 perf)如何将计数器与指令相关联?
How does a system wide profiler (e.g. perf) correlate counters with instructions?
我正在尝试了解系统范围的分析器是如何工作的。我们以 linux perf 为例。对于一定的分析时间,它可以提供:
- 各种聚合硬件性能计数器
- 每个用户花费的时间和硬件计数器(例如#instructions)space进程和内核space函数
- 关于上下文切换的信息
- 等等
我几乎可以肯定的第一件事是,该报告只是对实际情况的估计。所以我认为有一些内核模块 以特定的采样率 启动软件中断。采样率越低,探查器开销越低。中断可以读取存储性能计数器的模型特定寄存器。
下一部分是将计数器与机器上 运行 的软件相关联。 那是我不明白的部分。
那么探查器从哪里获取数据呢?
你可以询问任务调度器,看看你打断他时 运行 是什么吗? 这不会影响
调度程序的执行(例如,而不是继续
中断的功能,它只会安排另一个,使
探查器结果不准确)。 task_struct 对象的列表是否可用?
- 探查器如何关联硬件
指标甚至在指令级别?
这几乎回答了您的所有三个问题。
分析包括两种类型:计数和抽样。计数措施
全面的
数字
整个执行过程中的事件而不提供任何洞察力
关于
这
指令或函数
生成的
他们
.在
另一方面,
抽样给出了相关性
代码的事件
通过捕获的指令指针样本
.
采样时,
内核指示处理器在以下情况下发出中断
被选中的
事件计数器超过
临界点。吨
他的中断被内核和采样数据捕获
包括说明书
指针
值存储到环形缓冲区中。缓冲区由用户空间定期轮询
性能工具及其内容
写入磁盘。
在post处理中,Instruction Pointer匹配到
二进制文件中的地址,可以翻译成函数名等
So I think there's some kernel module that launches software interrupts at a certain sampling rate.
Perf 不是模块,它是 Linux 内核的一部分,在
kernel/events/core.c and for every supported architecture and cpu model, for example arch/x86/kernel/cpu/perf_event*.c。但 Oprofile 是一个模块,具有类似的方法。
Perf 通常通过请求 CPU 的 PMU(性能监控单元)在某些硬件性能计数器(Yokohama, slide 5 "• 达到阈值时中断: 允许采样")。实际上可能实现为:
- select 一些 PMU 计数器
- 将其初始化为
-N
,其中N是采样周期(我们希望在N个事件后中断,例如,在200万个周期后perf record -c 2000000 -e cycles
,或者由perf计算和调整的一些N当没有设置额外选项或给出 -F
时)
- 将此计数器设置为需要的事件,并要求 PMU 在溢出时生成中断 (ARCH_PERFMON_EVENTSEL_INT)。它会在我们的计数器递增 N 之后发生。
所有现代 Intel 芯片都支持此功能,例如 Nehalem:https://software.intel.com/sites/default/files/76/87/30320 - Nehalem 性能监控单元编程指南
EBS - Event Based Sampling. A technique in which counters are pre-loaded with a large negative count, and they are configured to interrupt the processor on overflow. When the counter overflows the interrupt service routine capture profiling data.
因此,当您使用硬件 PMU 时,在定时器中断时不需要额外的工作来专门读取硬件 PMU 计数器。在任务切换时 save/restore PMU 状态有一些工作,但是 kernel/events/core.c 的 *_sched_in
/*_sched_out
不会更改当前线程的 PMU 计数器值,也不会将其导出到用户-space.
有一个处理程序:arch/x86/kernel/cpu/perf_event.c: x86_pmu_handle_irq
which finds the overflowed counter and calls perf_sample_data_init(&data, 0, event->hw.last_period);
记录当前时间,最后执行命令的IP(由于大多数英特尔微架构的乱序性,它可能不准确,有对于某些事件 - PEBS,perf record -e cycles:pp
),堆栈跟踪数据(如果在记录中使用了 -g
)等是有限的解决方法。然后处理程序将计数器值重置为 -N
(x86_perf_event_set_period, wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
- 注意 left
)
之前的减号
The lower the sampling rate, the lower the profiler overhead.
Perf 允许您使用 -F
选项设置目标采样率,-F 1000
表示大约 1000 irq/s。由于高开销,不建议使用高速率。十年前,英特尔 VTune 建议不要超过 1000 irq/s (http://www.cs.utah.edu/~mhall/cs4961f09/VTune-1.pdf “尝试在每个逻辑 CPU. 每秒获取大约 1000 个样本” ), perf 通常不允许非 root 用户使用过高的速率(当 "perf interrupt took too long" 时自动调低速率 - 检查你的 dmesg
;同时检查 sysctl -a|grep perf
,例如 kernel.perf_cpu_time_max_percent=25
- 这意味着 perf 将尝试使用不超过 CPU)
的 25%
Can you interrogate for example the task scheduler to find out what was running when you interrupted him?
没有。但是您可以在 sched_switch
或其他计划事件中启用跟踪点(列出计划中所有可用的:perf list 'sched:*'
),并将其用作 perf 的分析事件。您甚至可以要求 perf 在此跟踪点记录堆栈跟踪:
perf record -a -g -e "sched:sched_switch" sleep 10
Won't that affect the execution of the scheduler
启用跟踪点将使添加一些性能事件采样工作到具有跟踪点的函数
Is the list of task_struct objects available?
仅通过 ftrace...
Information about context switches
这是软件性能事件,只需使用 sched/core.c 中的 PERF_COUNT_SW_CONTEXT_SWITCHES
事件调用 perf_sw_event
(间接)。直接调用示例-迁移软件事件:kernel/sched/core.c set_task_cpu():p->se.nr_migrations++; perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, NULL, 0);
PS:Gregg 在 Linux 中有关于 perf、ftrace 和其他分析和跟踪子系统的精彩幻灯片:http://www.brendangregg.com/linuxperf.html
我正在尝试了解系统范围的分析器是如何工作的。我们以 linux perf 为例。对于一定的分析时间,它可以提供:
- 各种聚合硬件性能计数器
- 每个用户花费的时间和硬件计数器(例如#instructions)space进程和内核space函数
- 关于上下文切换的信息
- 等等
我几乎可以肯定的第一件事是,该报告只是对实际情况的估计。所以我认为有一些内核模块 以特定的采样率 启动软件中断。采样率越低,探查器开销越低。中断可以读取存储性能计数器的模型特定寄存器。
下一部分是将计数器与机器上 运行 的软件相关联。 那是我不明白的部分。
那么探查器从哪里获取数据呢?
你可以询问任务调度器,看看你打断他时 运行 是什么吗? 这不会影响 调度程序的执行(例如,而不是继续 中断的功能,它只会安排另一个,使 探查器结果不准确)。 task_struct 对象的列表是否可用?
- 探查器如何关联硬件 指标甚至在指令级别?
这几乎回答了您的所有三个问题。
分析包括两种类型:计数和抽样。计数措施 全面的 数字 整个执行过程中的事件而不提供任何洞察力 关于 这 指令或函数 生成的 他们 .在 另一方面, 抽样给出了相关性 代码的事件 通过捕获的指令指针样本 . 采样时, 内核指示处理器在以下情况下发出中断 被选中的 事件计数器超过 临界点。吨 他的中断被内核和采样数据捕获 包括说明书 指针 值存储到环形缓冲区中。缓冲区由用户空间定期轮询 性能工具及其内容 写入磁盘。 在post处理中,Instruction Pointer匹配到 二进制文件中的地址,可以翻译成函数名等
So I think there's some kernel module that launches software interrupts at a certain sampling rate.
Perf 不是模块,它是 Linux 内核的一部分,在 kernel/events/core.c and for every supported architecture and cpu model, for example arch/x86/kernel/cpu/perf_event*.c。但 Oprofile 是一个模块,具有类似的方法。
Perf 通常通过请求 CPU 的 PMU(性能监控单元)在某些硬件性能计数器(Yokohama, slide 5 "• 达到阈值时中断: 允许采样")。实际上可能实现为:
- select 一些 PMU 计数器
- 将其初始化为
-N
,其中N是采样周期(我们希望在N个事件后中断,例如,在200万个周期后perf record -c 2000000 -e cycles
,或者由perf计算和调整的一些N当没有设置额外选项或给出-F
时) - 将此计数器设置为需要的事件,并要求 PMU 在溢出时生成中断 (ARCH_PERFMON_EVENTSEL_INT)。它会在我们的计数器递增 N 之后发生。
所有现代 Intel 芯片都支持此功能,例如 Nehalem:https://software.intel.com/sites/default/files/76/87/30320 - Nehalem 性能监控单元编程指南
EBS - Event Based Sampling. A technique in which counters are pre-loaded with a large negative count, and they are configured to interrupt the processor on overflow. When the counter overflows the interrupt service routine capture profiling data.
因此,当您使用硬件 PMU 时,在定时器中断时不需要额外的工作来专门读取硬件 PMU 计数器。在任务切换时 save/restore PMU 状态有一些工作,但是 kernel/events/core.c 的 *_sched_in
/*_sched_out
不会更改当前线程的 PMU 计数器值,也不会将其导出到用户-space.
有一个处理程序:arch/x86/kernel/cpu/perf_event.c: x86_pmu_handle_irq
which finds the overflowed counter and calls perf_sample_data_init(&data, 0, event->hw.last_period);
记录当前时间,最后执行命令的IP(由于大多数英特尔微架构的乱序性,它可能不准确,有对于某些事件 - PEBS,perf record -e cycles:pp
),堆栈跟踪数据(如果在记录中使用了 -g
)等是有限的解决方法。然后处理程序将计数器值重置为 -N
(x86_perf_event_set_period, wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
- 注意 left
)
The lower the sampling rate, the lower the profiler overhead.
Perf 允许您使用 -F
选项设置目标采样率,-F 1000
表示大约 1000 irq/s。由于高开销,不建议使用高速率。十年前,英特尔 VTune 建议不要超过 1000 irq/s (http://www.cs.utah.edu/~mhall/cs4961f09/VTune-1.pdf “尝试在每个逻辑 CPU. 每秒获取大约 1000 个样本” ), perf 通常不允许非 root 用户使用过高的速率(当 "perf interrupt took too long" 时自动调低速率 - 检查你的 dmesg
;同时检查 sysctl -a|grep perf
,例如 kernel.perf_cpu_time_max_percent=25
- 这意味着 perf 将尝试使用不超过 CPU)
Can you interrogate for example the task scheduler to find out what was running when you interrupted him?
没有。但是您可以在 sched_switch
或其他计划事件中启用跟踪点(列出计划中所有可用的:perf list 'sched:*'
),并将其用作 perf 的分析事件。您甚至可以要求 perf 在此跟踪点记录堆栈跟踪:
perf record -a -g -e "sched:sched_switch" sleep 10
Won't that affect the execution of the scheduler
启用跟踪点将使添加一些性能事件采样工作到具有跟踪点的函数
Is the list of task_struct objects available?
仅通过 ftrace...
Information about context switches
这是软件性能事件,只需使用 sched/core.c 中的 PERF_COUNT_SW_CONTEXT_SWITCHES
事件调用 perf_sw_event
(间接)。直接调用示例-迁移软件事件:kernel/sched/core.c set_task_cpu():p->se.nr_migrations++; perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, NULL, 0);
PS:Gregg 在 Linux 中有关于 perf、ftrace 和其他分析和跟踪子系统的精彩幻灯片:http://www.brendangregg.com/linuxperf.html