用户空间(Linux)中是否有高分辨率时钟(us)?

rdi*_*503 1 c++ clock linux-kernel low-latency c++-chrono

您是否知道 Linux 用户空间中高分辨率时钟(最小微秒)的任何​​ C/C++ 实现(即使它不可移植)?

目标是测量一些低延迟操作的时间间隔。我测量到内核空间时钟有时会导致延迟峰值。

根据我对 Red Hat 7.2 的研究:

  • std::chrono::high_resolution_clock 最大分辨率为毫秒;
  • Clock_gettime CLOCK_MONOTONIC 和 CLOCK_REALTIME 通过内核系统调用执行;
  • gettimeofday是通过内核系统调用执行的;
  • Clock_gettime CLOCK_MONOTONIC_COARSE 和 CLOCK_REALTIME_COARSE 在用户空间执行,但最大分辨率为毫秒;

谢谢。

Max*_*kin 6

rdtsc一种选择是通过函数使用指令__builtin_ia32_rdtsc。在现代 Intel CPU 上,rdtsc任何 CPU 频率都以基本时钟速率计时,因此您可以通过将计数器除以基本(而非提升)CPU 频率(以 GHz 为单位),将计数器转换为纳秒:

#include <regex>
#include <string>
#include <fstream>
#include <iostream>

double cpu_base_frequency() {
    std::regex re("model name\\s*:[^@]+@\\s*([0-9.]+)\\s*GHz");
    std::ifstream cpuinfo("/proc/cpuinfo");
    std::smatch m;
    for(std::string line; getline(cpuinfo, line);) {
        regex_match(line, m, re);
        if(m.size() == 2)
            return std::stod(m[1]);
    }
    return 1; // Couldn't determine the CPU base frequency. Just count TSC ticks.
}

double const CPU_GHZ_INV = 1 / cpu_base_frequency();

int main() {
    auto t0 = __builtin_ia32_rdtsc();
    auto t1 = __builtin_ia32_rdtsc();
    std::cout << (t1 - t0) * CPU_GHZ_INV << "nsec\n";
}
Run Code Online (Sandbox Code Playgroud)

来自英特尔文档的更多信息:

恒定的 TSC行为可确保每个时钟周期的持续时间一致,并支持将 TSC 用作挂钟定时器,即使处理器内核更改频率也是如此。这是向前发展的建筑行为。

不变的 TSC将在所有 ACPI P、C 和 T 状态下以恒定速率运行。这是向前发展的建筑行为。在具有不变 TSC 支持的处理器上,操作系统可以使用 TSC 进行挂钟计时器服务(而不是 ACPI 或 HPET 计时器)。TSC 读取效率更高,并且不会产生与环转换或访问平台资源相关的开销。

不变TSC基于不变计时硬件(称为始终运行定时器或 ART),该硬件以核心晶体时钟频率运行。

可扩展总线频率编码在位字段 MSR_PLATFORM_INFO[15:8] 中,标称 TSC 频率可以通过将该数字乘以 100 MHz 的总线速度来确定。