c - getrusage 返回四舍五入的数字

标签 c linux

我正在尝试使用 usage 测量各种函数调用的资源使用时间(用户和系统)。 我发现我得到的结果大约为 10 毫秒,例如 0 秒、70000 秒、10000 秒等。如果有办法为 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/

相关文章:

c++ - 对 char a ='abc' 感到困惑;行为C编程

c++ - 如何通过交换边使图强连通

linux - 如何更改 openwrt Makefiles 以仅生成一个图像

linux - 安装和解锁加密的 Truecrypt 驱动器

c++ - 我在使用 z3 :timeout correctly with C++ interface for Linux?

c - 为什么我们要将一段代码放在大括号内?

c - x86 上的有符号和无符号算术实现

c++ - C/C++ 相当于 C# System.Net.Mail

c - C 语言简单程序,用于将字符串附加到目录中的所有文件

linux - 比较两个 csv 文件并将缺失的数据写入单独的 csv