【发布时间】:2011-12-15 15:05:48
【问题描述】:
我正在寻找 Windows 高分辨率性能计数器 API 的 Linux 替代方案,尤其是以下 API 函数:
谢谢。
【问题讨论】:
我正在寻找 Windows 高分辨率性能计数器 API 的 Linux 替代方案,尤其是以下 API 函数:
谢谢。
【问题讨论】:
查看带有CLOCK_MONOTONIC_RAW 标志的clock_gettime() 和clock_getres()。
这里也是一个如何使用它的例子:
【讨论】:
stopwatch,你必须使用 gcc 标志 -std=gnu99 而不是 -std=c99 才能工作。只是添加,因为我为此工作了一个小时:)
perf 工具已经随内核一起提供了一段时间,现在可能会满足您的需求。它有很多选项,所以请仔细研究;)
编辑:算了,我以为你在谈论 CPU 性能计数器。
【讨论】:
perf 是一个分析工具,可以为您提供许多指标,但它甚至与QueryPerformanceCounter 在 Windows 上所做的相比还差得远。所以perf 不是答案。 clock_gettime () 是为您提供高精度(硬件)贴墙时间的原因。使用它。
Linux perf_event_open 系统调用
此系统调用以与架构无关的方式公开多个性能计数器。
man perf_event_open 记录了可用的计数器,其中包括您所期望的所有最基本的东西:
config = PERF_COUNT_HW_CPU_CYCLES)type = PERF_TYPE_HW_CACHE)config = PERF_COUNT_HW_BRANCH_MISSES)PERF_COUNT_SW_PAGE_FAULTS) 和上下文切换 (PERF_COUNT_SW_CONTEXT_SWITCHES)我在How to get the CPU cycle count in x86_64 from C++? 处给出了循环计数
perf_event_open.c
#include <asm/unistd.h>
#include <linux/perf_event.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <inttypes.h>
static long
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
{
int ret;
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags);
return ret;
}
int
main(int argc, char **argv)
{
struct perf_event_attr pe;
long long count;
int fd;
uint64_t n;
if (argc > 1) {
n = strtoll(argv[1], NULL, 0);
} else {
n = 10000;
}
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(struct perf_event_attr);
pe.config = PERF_COUNT_HW_CPU_CYCLES;
pe.disabled = 1;
pe.exclude_kernel = 1;
// Don't count hypervisor events.
pe.exclude_hv = 1;
fd = perf_event_open(&pe, 0, -1, -1, 0);
if (fd == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
/* Loop n times, should be good enough for -O0. */
__asm__ (
"1:;\n"
"sub $1, %[n];\n"
"jne 1b;\n"
: [n] "+r" (n)
:
:
);
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
read(fd, &count, sizeof(long long));
printf("%lld\n", count);
close(fd);
}
【讨论】: