【问题标题】:why using clock() get minus number in measuring CPU time为什么在测量 CPU 时间时使用时钟()得到负数
【发布时间】:2012-05-30 09:45:17
【问题描述】:

我正在使用 clock() 来测量我的算法的 CPU 时间量。

代码如下:

start_time = clock();
//code to be timed
.
end_time = clock();
elapsed_time = (end_time - start_time)*1000 / CLOCKS_PER_SEC;

printf("Time taken %d seconds %d milliseconds\n", elapsed_time/1000, elapsed_time%1000 );

但结果是“0 秒 -175 毫秒”。我不明白为什么。 似乎“1 秒 349 毫秒”实际上可能需要 10 分钟或更长时间。 这很常见吗?

【问题讨论】:

  • 您是否要为一个分叉的程序计时?
  • 是的,这正是我想做的。
  • 请向我们展示更多代码——包括变量类型等。并确保您在此处显示的内容与您正在编译和测试的内容完全相同(例如,如果您将 printf 更改为使用 %lld,在此处显示)。并告诉我们您使用的是什么平台(以及您是为 32 位还是 64 位架构构建)。

标签: c++ clock


【解决方案1】:

分叉是一种特殊情况,这种类型的代码将导致负时间。原因之一是,clock() 将返回自程序启动以来的时钟滴答数。

提醒一下,start_time 中的值将被复制到子进程中。

  • 对于父进程,时间应该是正数。因为start_timeend_time 的时钟滴答计数是针对同一个进程的。

  • 对于子进程,由于它仅在之后 fork() 启动,clock() 将返回程序从此时开始运行的时钟滴答数。不记录fork()之前的时间。

    由于计数时钟滴答的起始参考不同:

    • start_time 是从 parent 进程开始到第一个 clock() 的时钟滴答数
    • end_time 是从 child 进程开始到第二个 clock())
    • 的时钟滴答数

    这可能会导致负面结果。如果子进程运行的时间足够长以超过父进程启动的时间量,也可能会产生积极的结果。

编辑

我不确定预期的时间是多少,但是如果您想计算:父进程的时钟滴答声从开始到结束,子进程的时钟滴答声从fork() 到结束,然后修改您的代码以覆盖start_time 在子进程中具有新值 clock()。或者您可以将start_time 设置为 0。

【讨论】:

  • 嗨 nhahtdh,我已经禁止多线程。所以应该不是fork case吧?
  • 我不明白。程序可以运行多长时间?你会在两者之间产生线程/进程吗?
  • 我的意思是我禁用了线程池的使用。它运行大约一个小时。
  • 在这种情况下它可能溢出。你能在运行程序的机器上检查sizeofclock_t吗?
  • 似乎 clock_t 这里是 8bytes。我已经删除了 *1000 并将 elapsed_time 修改为无符号长。您还有其他建议吗?
【解决方案2】:

如果 start_time 和 end_time 是 32 位整数,则它们只能保持大约 2147 秒(大约 35 分钟),然后再转为负数,因为 CLOCKS_PER_SEC 是 1000000。

但比这更糟糕,因为你将差值乘以 1000,这意味着如果超过 2.147 秒就会溢出。

另一方面,如果它们不是 32 位整数,则说明您使用了错误的 printf 格式说明符(并且您可能会收到并忽略来自编译器的警告),因此您会看到垃圾。

【讨论】:

  • 它们都是“clock_t”的类型。会溢出吗?是的,我会用“%f”再试一次。谢谢!
  • IIRC,clock_t 是无符号长的,这意味着您的算术将在 32 位构建中溢出,而您的 printf 将在 64 位构建中打印垃圾。而且……我希望这不会侮辱您的智力,但是切换到 %f 不会有帮助,除非您也将所有变量都切换为双精度数。
猜你喜欢
  • 1970-01-01
  • 2013-12-25
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2013-06-30
  • 1970-01-01
相关资源
最近更新 更多