【问题标题】:CPU time is always zero :(CPU时间始终为零:(
【发布时间】:2012-05-01 03:10:51
【问题描述】:

我正在尝试使用以下代码测量 CPU 时间。

timespec time1, time2, temp_time;

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
 int i;
 int cpu_sum = 0;


 for (i = 0; i < nelements; i++) {

  cpu_sum += array[i];

 }    
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
temp_time.tv_sec = time2.tv_sec - time1.tv_sec;
printf( sum: %d using CPU in %lf ms \n",cpu_sum, temp_time.tv_sec);

但我总是得到 0.000 毫秒的时间 知道这里出了什么问题。

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 您没有检查clock_gettime(3) 调用是否有错误返回;检查返回值,如果返回错误,使用perror(3)输出错误信息。
  • clock_gettime 不应该在给定有效参数时返回错误。
  • @R..:并非所有时钟都适用于所有平台; user958263 没有显示sysconf(3) 代码来验证他正在使用的时钟在他的平台上是否可用,所以我很好奇它是否因为不支持而失败。

标签: c++ c time cpu


【解决方案1】:
  1. 您通过将错误的参数类型传递给 printftime_t,可能是 long,而不是 double)来调用未定义的行为。

  2. tv_sec 仅包含时间的整个秒数部分。您还需要使用tv_nsec 来获取纳秒部分。

尝试类似:

temp_time.tv_sec = time2.tv_sec - time1.tv_sec;
temp_time.tv_nsec = time2.tv_nsec - time2.tv_nsec;
if (temp_time.tv_nsec < 0) {
    temp_time.tv_nsec += 1000000000;
    temp_time.tv_sec--;
}
printf("%lld.%.9ld\n", (long long)temp_time.tv_sec, (long)temp_time.tv_nsec);

【讨论】:

  • time_t 可以是整数或浮点类型,POSIX 允许。
  • 它可能是,但实际上它永远不会。即使是这样,在 timespec 中使用时,它仍然只会存储整数。
  • @dreamlax:仅供参考,POSIX 2008 要求它是整数类型。
  • @R..:很高兴知道。我从未遇到过使用浮动time_t 的系统,但每次我使用time_t 类型时,我都会考虑这种可能性。展望未来,这将不再是一个问题!
【解决方案2】:

以上内容不会按原样编译,但有一个明显的问题:您只查看tv_sec 字段而不是tv_nsec 字段。这两个以整秒为单位的 tv_sec 值很可能是相同的,因为经过的 CPU 时间不到整整一秒。

减去两个 timespec 结构值(未经测试):

void ts_delta(struct timespec *result, struct timespec *a, struct timespec *b) {
    int borrow = 0;
    long n = a->tv_nsec - b->tv_nsec;

    if (n < 0) { /* nsec underflow; borrow 1 from seconds */
        n += 1000000000L;
        borrow = 1;
    }
    result->tv_nsec = n;
    result->tv_sec = a->tv_sec - b->tv_sec - borrow;
}

【讨论】:

  • @R..:我做到了!我通常依靠使用-W -Wall 编译来捕获C 中的类型错误。
  • 在这种情况下如何打印时间?
  • @R.. 的答案有一个打印结果的好方法。请注意,我不知道您的系统是否甚至可以捕获一小部分所花费的时间(例如,如果nelements 只有几万)。
  • 如果是 Linux,clock_gettime 在现代系统上实际上具有纳秒精度。对于 cpu 时间(在某些方面比实时更容易测量),它几乎肯定是那么精确。
【解决方案3】:

我假设您正在尝试使用 Linux。

在我的系统中,它打印如下。您可以检查并告诉我它是否有效。

ayub@gentux ~ $ cat cputime.c
#include <stdio.h>
#include <time.h>

int main(void)
{
  struct timespec time1, time2, temp_time;

  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
  int i;
  int cpu_sum = 0;
  static int array[1000]; /* 'static' to make the array initialized to zero by default (for demo) */
  int nelements = 1000;
  long diff = 0;

  array[0] = 10;
  for (i = 0; i < nelements; i++) {
    cpu_sum += array[i];
  }    
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
  temp_time.tv_sec = time2.tv_sec - time1.tv_sec;
  temp_time.tv_nsec = time2.tv_nsec - time1.tv_nsec;
  diff = temp_time.tv_sec * 1000000000 + temp_time.tv_nsec; /* total ns */
  printf("Sum: %d using CPU in %lf ms \n", cpu_sum, (double) diff/1000000); /* now we print as milisecond */

  return 0;
}

ayub@gentux ~ $ gcc -o cputime cputime.c -lrt
ayub@gentux ~ $ time ./cputime
Sum: 10 using CPU in 0.003197 ms 

real    0m0.001s
user    0m0.000s
sys     0m0.000s
ayub@gentux ~ $ ./cputime 
Sum: 10 using CPU in 0.002599 ms

【讨论】:

    【解决方案4】:

    gnu libc 手册有一些很好的信息,甚至包括一个示例减法函数

    http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html

    【讨论】:

      猜你喜欢
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 2016-05-02
      • 2012-01-16
      • 2020-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多