PERF_COUNT_SW_TASK_CLOCK 的计量单位

Unit of measurement of PERF_COUNT_SW_TASK_CLOCK

perf_event_open中,可以在PERF_COUNT_SW_TASK_CLOCK中传递的标志之一,其描述是:

     This reports a clock count specific to the task that is running. 

但是,没有记载这个计时器的单位是什么。

那么,如何将由此返回的数字转换为纳秒?

我们为什么不进行一个小测试来弄清楚呢。我将使用一个我知道 time.htime() 单位的计时器,并将其与 PERF_COUNT_SW_TASK_CLOCK 进行比较。他们计算时间的方式不同,我希望 PERF_COUNT_SW_TASK_CLOCK 的结果更小,但数量级相同。

这是我使用的代码:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>

void main() {
    // Setting up the perf fd
    struct perf_event_attr pe;
    memset(&pe, 0, sizeof(struct perf_event_attr));
    pe.type = PERF_TYPE_SOFTWARE;
    pe.size = sizeof(struct perf_event_attr);
    pe.config = PERF_COUNT_SW_TASK_CLOCK;
    pe.disabled = 1;
    pe.exclude_kernel = 1;
    pe.exclude_hv = 1;
    // glibc doesn't expose perf_event_open, so directly calling the syscall
    int fd = syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0);
    ioctl(fd, PERF_EVENT_IOC_RESET, 0);
    ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

    // For comparing with a known unit
    time_t time_start = time(0);
    long long count_start;
    read(fd, &count_start, sizeof(long long));

    // Very long calculation
    int a = 1;
    for (int i=0; i<1000000; i++)
        for (int j=0; j<10000; j++)
            a++;

    // Results
    ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
    long long count_finish;
    read(fd, &count_finish, sizeof(long long));
    time_t time_finish = time(0);

    printf("time(): %d\n", time_finish-time_start);
    printf("PERF_COUNT_SW_TASK_CLOCK: %lld\n", count_finish-count_start);
    return;
}

结果是

time(): 23
PERF_COUNT_SW_TASK_CLOCK: 22565098436

看来它已经以纳秒为单位计算了。