问题描述
在 perf_event_open
中,可以在 PERF_COUNT_SW_TASK_CLOCK
中传递的标志之一,其描述为:
This reports a clock count specific to the task that is running.
但是,没有记录这个计时器的单位是什么。
那么,如何将由此返回的数字转换为纳秒?
解决方法
我们为什么不进行一个小测试来弄清楚。我将使用一个我知道单位的计时器,time.h
的 time()
,并将其与 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,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,-1,0);
ioctl(fd,PERF_EVENT_IOC_RESET,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
所以它似乎已经以纳秒为单位计算了。