我正在尝试使用 rusage 测量各种函数调用的资源使用时间(用户和系统)。
我发现我得到的结果大约是 10 毫秒,如 0 70000us、10000us 等。请告诉我是否有办法为 getrusage 设置精度/粒度。

我的程序很简单:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>

int main(){
  struct rusage usage;
  struct timeval start, end;
  int i, j, k = 0;

  getrusage(RUSAGE_SELF, &usage);
  start = usage.ru_utime;
  printf("buffer check\n");
  char *str = "---";
  int arr[100],ctr;

  for(ctr = 0;ctr<100;ctr++){

    arr[ctr] = ctr + 1000;

  }

  for (i = 0; i < 10000; i++) {
     for (j = 0; j < 10000; j++) {
      k += 20;
  }
 }

 getrusage(RUSAGE_SELF, &usage);
 end = usage.ru_utime;

 printf("Started at: %ld.%lds\n", start.tv_sec, start.tv_usec);
 printf("Ended at: %ld.%lds\n", end.tv_sec, end.tv_usec);

 return 1;
}

结果
开始于:0.0s
结束于:0.2000000s

我添加了另一个 for 循环并得到如下结果:
开始于:0.0s
结束于:0.7000000s
我浏览了很多,以找到一种可能的方法来获得准确的计时。在 linux 源代码等中遇到了 3 个参数 getrusage,但我不确定如何使用它,因为它需要任务指针作为第一个参数。其中一个链接表明它与 linux 版本有关。无论如何,请让我知道是否有任何方法可以设置精度/粒度。如果没有,请告诉我是否有任何替代 getrusage 的方法。 gettimeofDay 似乎没有提供资源使用细节,所以如果我无法设置精度,请寻找 getrusage 的实际实现。

最佳答案

许多操作系统没有对进程使用的时间进行精确计算。在许多情况下,读取每个上下文切换和系统调用的时钟成本太高,在其他情况下,硬件甚至可能没有允许您以任何精度计时的时钟。

getrusage 获得的一种非常常用的记帐方法是使用 100Hz(通常为 100Hz,尽管 64Hz 和 1024Hz 也很常见)的计时器中断,它对中断发生时系统上发生的情况进行采样。因此,内核每秒 100 次检查当前正在运行的内容和位置(ru_utime 的用户空间或 ru_stime 的内核空间)并增加计数器。然后将该计数器解释为您的程序运行了 10 毫秒。

你可以在你的系统上试验 clock_gettime,看看它是否有每个进程的计数器,有时这些计数器可能比 getrusage 计数器更精确。但我不会抱有希望,如果 10 毫秒的分辨率是 getrusage 可以做到的最佳分辨率,那么 clock_gettime 可能根本不会有更好的分辨率或任何每个进程的时钟。

如果操作系统中的时钟对于您的测量来说不够好,您唯一的选择就是重复您的测试运行几分钟,然后将您得到的任何结果除以运行次数。
gettimeofday 更精确这一事实并没有多大意义。 gettimeofday 可能相对昂贵。想一想内核为准确跟踪进程的用户和系统时间必须做的工作。每次进行系统调用时,它都必须使用两次时间戳(一次用于系统调用的开始,一次用于结束),以便跟踪您使用了多少系统时间。为了跟踪用户时间,每次系统切换到另一个进程时都需要时间戳。许多系统确实会跟踪第二个,但不是第一个,因为系统调用比进程上下文切换更常见(这就是为什么我建议检查 clock_gettime 因为它可以有一个计时器来累积进程的总系统和用户时间) .

现代系统中的时钟非常烦人,因为即使获取时间戳是最常见的系统调用之一,我们仍然经常需要在慢速总线中拖网并进行重锁定以获取它们。其他解决方案如 cpu 上的循环计数器已被使用,但这些解决方案是出了名的不准确,因为它们可能在 CPU 之间不同步,可能具有可变频率,可以在操作系统的控制之外停止等,并且您需要知道您的 CPU 的确切型号,以便能够可靠地使用它们。操作系统有很多启发式方法来确定使用哪些时钟,但这可能意味着两台几乎相同的机器之间存在巨大差异。一个人可能会得到一个亚纳秒精度的周期计数器,读取一条指令需要花费一条指令,而另一个需要通过 ISA 总线到达 30 年前的芯片设计,具有微秒精度或更差,需要数千个周期才能读取。

关于c - getrusage 返回四舍五入的数字,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19043873/

10-08 20:34