Linux替代Windows高分辨率性能计数器API
我正在寻找Linux替代Windows高分辨率性能计数器API,特别是以下API函数:Linux替代Windows高分辨率性能计数器API,linux,performancecounter,Linux,Performancecounter,我正在寻找Linux替代Windows高分辨率性能计数器API,特别是以下API函数: 谢谢。随内核提供的perf工具现在可能满足了您的需要。它有大量的选项,因此请仔细研究;) 编辑:算了吧,我还以为你说的是CPU性能计数器。请参阅带有时钟\u单调\u原始标志和 下面是一个如何使用它的示例: Linuxperf\u event\u open系统调用 此系统调用以完全不可知的方式公开多个性能计数器 man perf_event_open记录了可用的计数器,其中包括您期望的所有最基本
谢谢。随内核提供的
perf
工具现在可能满足了您的需要。它有大量的选项,因此请仔细研究;)
编辑:算了吧,我还以为你说的是CPU性能计数器。请参阅带有时钟\u单调\u原始
标志和
下面是一个如何使用它的示例:
perf\u event\u open
系统调用
此系统调用以完全不可知的方式公开多个性能计数器
man perf_event_open
记录了可用的计数器,其中包括您期望的所有最基本的内容:
- 周期计数(
)config=PERF\u count\u HW\u CPU\u周期
- 缓存命中和未命中(
)type=PERF\u type\u HW\u缓存
- 分支未命中(
)config=PERF\u COUNT\u HW\u分支未命中
- 内核软件可见事件,如页面错误(
)和上下文开关(PERF\u COUNT\u SW\u page\u faults
)PERF\u COUNT\u SW\u context\u switches
#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);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静长
性能事件打开(结构性能事件属性*硬件事件,pid,
int cpu、int group_fd、无符号长标志)
{
int ret;
ret=syscall(_unr_perf_event_open,hw_event,pid,cpu,
组(fd,flags),;
返回ret;
}
int
主(内部argc,字符**argv)
{
结构性能事件属性;
长计数;
int-fd;
uint64\u t n;
如果(argc>1){
n=strtoll(argv[1],NULL,0);
}否则{
n=10000;
}
memset(&pe,0,sizeof(struct perf_event_attr));
pe.type=性能类型硬件;
pe.size=sizeof(结构性能事件属性);
pe.config=性能计数\u硬件\u CPU \u周期;
pe.disabled=1;
pe.exclude_kernel=1;
//不要计算虚拟机监控程序事件。
pe.hv=1;
fd=性能事件打开(&pe,0,-1,-1,0);
如果(fd==-1){
fprintf(stderr,“打开引线%llx\n时出错”,pe.config);
退出(退出失败);
}
ioctl(fd,性能事件IOC重置,0);
ioctl(fd,性能事件IOC启用,0);
/*循环n次,对于-O0应该足够好*/
__阿斯马(
“1:;\n”
“子$1,%[n];\n”
“jne 1b;\n”
:[n]“+r”(n)
:
:
);
ioctl(fd,性能事件IOC禁用,0);
读取(fd、计数和大小(长));
printf(“%lld\n”,计数);
关闭(fd);
}
感谢您的快速回复。我需要在cpp程序中使用这些函数。我该怎么做?@user1087995:perf
是一个分析工具,它可以为您获取许多指标,但它甚至不接近Windows上的QueryPerformanceCounter
功能。因此,perf
不是答案clock_gettime()
为您提供高精度(硬件)墙壁时间。使用它。嗯,好吧,当我看到“性能计数器”时,我真的认为CPU性能计数器是指,但这里似乎不是这样。我仍然无法理解:当我尝试使用clock\u gettime(clock\u id,&tp);tp只返回所经过的时间(以微秒和秒为单位),我需要的是周期数(=tickes)。@user1087995:CPU周期?但是什么呢?您的程序可以安排在不同的CPU上,除非您显式地设置CPU相关性。这种衡量绩效的方法几乎已经过时。但如果你仍然想这样做,看看RDTSC——但为了获得精度,你必须知道CPU频率,以便将周期数转换成时间。然而,CPU频率可能是非恒定的,即Intel有用于节能的Turbo Boost技术。换句话说,Windows有问题。@ScrollerBlaster:谢谢你的提示。我提供了一个新链接。虽然现在它略为C,并且也移植到了OS X。如果你想用C99支持编译秒表,你必须使用gcc标志-std=gnu99
,而不是-std=C99
,它才能工作。只是因为我花了一个小时才加上:)