Linux 替代 Windows 高分辨率性能计数器 API

Posted

技术标签:

【中文标题】Linux 替代 Windows 高分辨率性能计数器 API【英文标题】:Linux alternative to Windows high-resolution performance counter API 【发布时间】:2011-12-15 15:05:48 【问题描述】:

我正在寻找 Windows 高分辨率性能计数器 API 的 Linux 替代方案,尤其是以下 API 函数:

QueryPerformanceFrequency QueryPerformanceCounter

谢谢。

【问题讨论】:

【参考方案1】:

查看带有CLOCK_MONOTONIC_RAW 标志的clock_gettime()clock_getres()

这里也是一个如何使用它的例子:

stopwatch.h stopwatch.c stopwatch_example.c

【讨论】:

我还是想不通:当我尝试使用clock_gettime(clock_id, &tp); tp 仅以微秒和秒为单位返回经过的时间,我需要的是周期数(=tickes)。 @user1087995:CPU 周期?什么CPU呢?除非您明确设置 CPU 亲和性,否则您的程序可以安排在不同的 CPU 上。这种衡量性能的方法几乎已经过时了。但如果你仍然想走那条路,看看 RDTSC - en.wikipedia.org/wiki/Time_Stamp_Counter 但是为了获得精度,您必须知道 CPU 频率才能将周期数转换为时间。但是,CPU 频率可能不是恒定的,即英特尔有 Turbo Boost 技术来节能等。这样说吧 - Windows 是有缺陷的。 @ScrollerBlaster:感谢您的提示。我提供了一个新链接。虽然现在它有点 C 并且也移植到了 OS X。 如果你想用 C99 支持编译 stopwatch,你必须使用 gcc 标志 -std=gnu99 而不是 -std=c99 才能工作。只是添加,因为我为此工作了一个小时:)【参考方案2】:

perf 工具已经随内核一起提供了一段时间,现在可能会满足您的需求。它有很多选项,所以请仔细研究;)

编辑:算了,我以为你在谈论 CPU 性能计数器。

【讨论】:

感谢您的快速回复。我需要在 cpp 程序中使用这些功能。我该怎么做? @user1087995: perf 是一个分析工具,可以为您提供许多指标,但它甚至与QueryPerformanceCounter 在 Windows 上所做的相比还差得远。所以perf 不是答案。 clock_gettime () 是为您提供高精度(硬件)贴墙时间的原因。使用它。 嗯,好吧,当我看到“性能计数器”时,我真的以为 CPU 性能计数器是指的,但这里似乎不是这种情况。【参考方案3】:

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);

【讨论】:

以上是关于Linux 替代 Windows 高分辨率性能计数器 API的主要内容,如果未能解决你的问题,请参考以下文章

高分辨轨道阱液质联用质谱仪-HFX

超分辨率中根据原图生成测试集(低分辨图或高分辨图)

flexible.js移动端适配安卓高分辨不兼容问题

基于高分辨Orbitrap的氢氘交换质谱完整解决方案

沃特世推出SELECT SERIES MRT多反射飞行时间质谱平台,树立高分辨质谱性能新标杆

Linux 能替代 Windows 吗?