You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux系统调用getrusage的真实时间分辨率是多少?

getrusage 分辨率测量问题

我尝试通过如下简单程序测量getrusage的分辨率:

#include <cstdio>
#include <sys/time.h>
#include <sys/resource.h>
#include <cassert>

int main(int argc, const char *argv[]) {
    struct rusage u = {0};
    assert(!getrusage(RUSAGE_SELF, &u));
    size_t  cnt = 0;
    while(true) {
        ++cnt;
        struct rusage uz = {0};
        assert(!getrusage(RUSAGE_SELF, &uz));
        if(u.ru_utime.tv_sec != uz.ru_utime.tv_sec || u.ru_utime.tv_usec != uz.ru_utime.tv_usec) {
            std::printf("u:%ld.%06ld\tuz:%ld.%06ld\tcnt:%ld\n", 
                    u.ru_utime.tv_sec, u.ru_utime.tv_usec,
                    uz.ru_utime.tv_sec, uz.ru_utime.tv_usec,
                    cnt);
            break;
        }
    }
}

运行该程序时,通常得到如下类似输出:

ema@scv:~/tmp/getrusage$ ./gt
u:0.000562  uz:0.000563 cnt:1
ema@scv:~/tmp/getrusage$ ./gt
u:0.000553  uz:0.000554 cnt:1
ema@scv:~/tmp/getrusage$ ./gt
u:0.000496  uz:0.000497 cnt:1
ema@scv:~/tmp/getrusage$ ./gt
u:0.000475  uz:0.000476 cnt:1

上述运行结果似乎表明getrusage的分辨率约为1微秒,但我此前认为其分辨率应为1/getconf CLK_TCK(即100Hz,对应10毫秒)。

现有两个疑问:

  • getrusage的真实分辨率是多少?
  • 我的测试方法是否存在错误?

测试环境备注:

  • 操作系统:Ubuntu 20.04
  • 内核版本:Linux scv 5.13.0-52-generic #59~20.04.1-Ubuntu SMP Thu Jun 16 21:21:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
  • 处理器:AMD Ryzen 9 5950X

回答

测试方法的核心错误

你测到的1微秒差值根本不是getrusage的统计分辨率,是两次系统调用过程中,你的进程实际消耗的CPU时间。
你的测试逻辑从根上就错了:第一次调用完getrusage之后,循环里第一次重试就检测到值变化,cnt恒为1,说明两次调用间隔远小于传统的10ms时钟tick周期——你现在的操作相当于按两次秒表,看到两次读数差了2毫秒,就声称秒表的分辨率是2毫秒,完全混淆了「测量间隔的差值」和「设备的最小分辨单位」。
正确的分辨率测量逻辑应该是:让进程持续跑CPU密集型负载(不要触发IO、睡眠),在运行过程中高频采样getrusage的返回值,统计所有读到的CPU时间值的最小步进,这个步进才是真实的统计分辨率。

Linux下getrusage的真实分辨率

它没有统一固定值,由内核版本、编译配置、CPU架构共同决定:

  • 2.6早期及更老版本内核:确实和CLK_TCK绑定,x86平台默认CLK_TCK=100,对应10毫秒分辨率。当时的进程CPU时间按时钟tick统计,每个tick触发一次计时中断,给当前正在CPU上运行的进程累加1个tick的CPU时间,不到1个tick的时间不会被统计。
  • 新版本内核(你使用的5.13版本属于该范畴):x86_64平台默认开启高精度CPU时间统计(对应内核配置项CONFIG_VIRT_CPU_ACCOUNTING_GEN、CONFIG_SCHED_HRTICK),直接利用CPU的TSC等高精度硬件计数器统计进程实际占用CPU的时长,不再依赖100Hz的时钟tick,统计精度可以达到纳秒级,最终通过rusage结构体返回时因为用的是timeval结构(秒+微秒字段),会截断到微秒单位,所以你能看到微秒级的数值变化。
  • 补充说明:哪怕是高精度统计模式,getrusage的返回值也不是绝对精准的,系统调用、上下文切换产生的CPU开销会被算进对应进程的统计值,短时间测量的噪声会非常明显。

补充验证方式

你可以写一段持续100ms左右的纯CPU计算逻辑(比如循环做整数自增,不要加任何sleep、IO操作),循环内每执行几千次运算就读一次ru_utime,把所有不重复的时间值打印出来,就能直观看到统计步进:如果数值是1微秒级连续变化的,就说明你的系统开了高精度统计;如果数值每次跳10毫秒,就是老的tick统计模式。
你当前测试里两次调用getrusage就差1微秒,本质是getrusage本身是系统调用,需要从用户态陷入内核态再返回,这期间CPU一直在执行你的进程代码,这部分1微秒左右的开销刚好被统计到了CPU时间里,只能侧面证明你的系统开了高精度统计,不能直接证明分辨率是1微秒。


内容的提问来源于stack exchange,提问作者Emanuele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:39:35