perf 记录的默认行为是什么?

问题描述

我很清楚perf 总是记录一个或多个事件,并且采样可以基于计数器或基于时间。但是当没有给出 -e-F 开关时,perf record认行为是什么? perf-record 的联机帮助页没有告诉您它在这种情况下的作用。

解决方法

默认事件是 cycles,通过在 perf script 之后运行 perf record 可以看出。在那里,您还可以看到默认采样行为是基于时间的,因为周期数不是恒定的。默认频率为 4000 Hz,可在 source code 中查看,并通过将文件大小或样本数与指定 -F 4000 的记录进行比较来检查。

perf wiki 表示速率为 1000 Hz,但对于 3.4 以上的内核而言,情况不再如此。

,

perf record 中的默认事件选择是在用户空间 perf 工具中完成的,该工具通常作为 linux 内核的一部分分发。使用 linux 内核源代码目录中的 make perf-src-tar-gz,我们可以制作 tar gz 以便快速重建或从 https://mirrors.edge.kernel.org/pub/linux/kernel/tools/perf 下载此类 tar。还有几个在线“LXR”交叉引用查看器,用于 linux 内核源代码,可以像 grep 一样使用它们来了解性能内部。

有为perf记录选择默认事件列表(evlist)的功能:__perf_evlist__add_default of tools/perf/util/evlist.c file

int __perf_evlist__add_default(struct evlist *evlist,bool precise)
{
    struct evsel *evsel = perf_evsel__new_cycles(precise);
    evlist__add(evlist,evsel);
    return 0;
}

在从选项解析零事件的情况下从 perf 记录实现调用:tools/perf/builtin-record.c: int cmd_record()

rec->evlist->core.nr_entries == 0 &&
    __perf_evlist__add_default(rec->evlist,!record.opts.no_samples)

并且 perf_evsel__new_cycles 将要求具有可选内核采样的硬件事件周期(PERF_TYPE_HARDWARE + PERF_COUNT_HW_CPU_CYCLES)和最大精确度check modifiers in man perf-list,它是使用 PEBS 或 IBS 的 EIP 采样滑动变通方法):

struct evsel *perf_evsel__new_cycles(bool precise)
{
    struct perf_event_attr attr = {
        .type   = PERF_TYPE_HARDWARE,.config = PERF_COUNT_HW_CPU_CYCLES,.exclude_kernel = !perf_event_can_profile_kernel(),};
    struct evsel *evsel;

    /*
     * Now let the usual logic to set up the perf_event_attr defaults
     * to kick in when we return and before perf_evsel__open() is called.
     */
    evsel = evsel__new(&attr);
    evsel->precise_max = true;

    /* use asprintf() because free(evsel) assumes name is allocated */
    if (asprintf(&evsel->name,"cycles%s%s%.*s",(attr.precise_ip || attr.exclude_kernel) ? ":" : "",attr.exclude_kernel ? "u" : "",attr.precise_ip ? attr.precise_ip + 1 : 0,"ppp") < 0)
    return evsel;
}

如果 perf_event_open 失败(无法访问硬件周期采样,例如在没有虚拟化 PMU 的虚拟化环境中),tools/perf/builtin-record.c: int record__open() 中会故障回复到软件 cpu-clock 采样,它调用 { {3}}:

bool perf_evsel__fallback(struct evsel *evsel,int err,char *msg,size_t msgsize)
{
    if ((err == ENOENT || err == ENXIO || err == ENODEV) &&
        evsel->core.attr.type   == PERF_TYPE_HARDWARE &&
        evsel->core.attr.config == PERF_COUNT_HW_CPU_CYCLES) {
        /*
         * If it's cycles then fall back to hrtimer based
         * cpu-clock-tick sw counter,which is always available even if
         * no PMU support.
         */
        scnprintf(msg,msgsize,"%s","The cycles event is not supported,trying to fall back to cpu-clock-ticks");

        evsel->core.attr.type   = PERF_TYPE_SOFTWARE;
        evsel->core.attr.config = PERF_COUNT_SW_CPU_CLOCK;

        return true;
    } ...
}