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.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, 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
看来它已经以纳秒为单位计算了。
在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, 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
看来它已经以纳秒为单位计算了。