【问题标题】:Why is my c++ clock() based function returning a negative value?为什么我的基于 c++ 时钟()的函数返回负值?
【发布时间】:2011-06-12 13:11:38
【问题描述】:

我还是 C++ 的新手,时钟功能是绝对的(意味着它计算你的睡眠时间),还是应用程序实际执行的时间?

我想要一种可靠的方法来产生 1 秒的精确间隔。我正在保存文件,所以我需要考虑这一点。我以毫秒为单位返回运行时,然后在其余时间休眠。

有没有更准确或更简单的方法来做到这一点?

编辑: 我遇到的主要问题是我得到一个负数:

double FCamera::getRuntime(clock_t* end, clock_t* start)
{
    return((double(end - start)/CLOCKS_PER_SEC)*1000);
}


clock_t start = clock();
doWork();
clock_t end = clock();

double runtimeInMilliseconds = getRuntime(&end, &start);

它给了我一个负数,这是怎么回事?

沃尔特

【问题讨论】:

  • 差异被称为“Wall time”与“CPU time”。
  • 我想我只是想通了,我想我是在传递地址并进行地址运算。
  • 我想通了,我在取消引用并减去地址。

标签: c++ timing clock


【解决方案1】:

clock() 返回程序启动后经过的时钟滴答数。如果要将时钟返回的值转换为秒除以CLOCKS_PER_SEC(反之亦然)。

只有一个陷阱,clock 用作程序执行开始的初始参考时刻可能因平台而异。要计算程序的实际处理时间,应该将时钟返回的值与初始调用时钟返回的值进行比较。

编辑

larsman 非常乐意在 cmets 中发布其他陷阱。我已将它们包含在此处以供将来参考。

  1. 在其他几个实现中,clock() 返回的值还包括通过wait(2)(或其他等待类型调用)收集其状态的任何孩子的时间。 Linux 在clock() 返回的值中不包含等待孩子的次数。

  2. 请注意,时间可以绕过去。在 CLOCKS_PER_SEC 等于 1000000 [根据 POSIX 规定] 的 32 位系统上,此函数将大约每 72 分钟返回相同的值。

EDIT2

搞砸了一段时间后,这是我的便携式 (Linux/Windows) msleep。不过要小心,我对 C/C++ 没有经验,而且很可能包含有史以来最愚蠢的错误。

#ifdef _WIN32

#include <windows.h>
#define msleep(ms) Sleep((DWORD) ms)

#else

#include <unistd.h>
inline void msleep(unsigned long ms) {
    while (ms--) usleep(1000);
}

#endif

【讨论】:

  • 您对clock 函数的看法是正确的,但是您的代码是实现延迟的一种相当低效的方法——它什么都不做会浪费CPU 周期。为什么不使用内置的sleep 调用呢?
  • 还有一个陷阱:“在其他几个实现中,clock() 返回的值还包括任何通过wait(2)(或其他等待类型调用)收集状态的孩子的时间). Linux 在clock() 返回的值中不包括等待孩子的次数。"
  • 还有一个:“请注意,时间可以回绕。在 CLOCKS_PER_SEC 等于 1000000 [根据 POSIX 要求] 的 32 位系统上,此函数将大约每 72 分钟返回相同的值。”但是由于您的进程会休眠一秒钟,因此这不太可能成为问题:)
  • 他不能使用睡眠,因为他需要在开始写入文件之前启动计时器。所以我会使用clock();或 timeGetTime() (这是一个 Windows 函数,自启动以来给出毫秒数,每 49 天包装一次)
【解决方案2】:

你错过了 * (pointer) , 您的参数是指针(clock_t 变量的地址) 所以,你的代码必须修改::

return((double(*end - *start)/CLOCKS_PER_SEC)*1000);

【讨论】:

    【解决方案3】:

    在windows下,可以使用:

    VOID WINAPI Sleep(
      __in  DWORD dwMilliseconds
    );
    

    在 linux 中,你会想要使用:

    #include <unistd.h>
    unsigned int sleep(unsigned int seconds);
    

    注意参数的区别——windows下的毫秒和linux下的秒。

    【讨论】:

      【解决方案4】:

      我的方法依赖于:

      int gettimeofday(struct timeval *tv, struct timezone *tz);

      它给出了自纪元以来的秒数和微秒数。根据 man 页面:

      The tv argument is a struct timeval (as specified in <sys/time.h>):
      
                 struct timeval {
                     time_t      tv_sec;     /* seconds */
                     suseconds_t tv_usec;    /* microseconds */
                 };
      

      所以我们开始:

      #include <sys/time.h>
      
      #include <iostream>
      #include <iomanip>
      
      static long myclock()
      {
          struct timeval tv; 
          gettimeofday(&tv, NULL);
          return (tv.tv_sec * 1000000) + tv.tv_usec;
      }
      
      double getRuntime(long* end, long* start)
      {
          return (*end - *start);
      }
      
      void doWork()
      {
          sleep(3);
      }
      
      int main(void)
      {
          long start = myclock();
          doWork();
          long end = myclock();
      
          std::cout << "Time elapsed: " << std::setprecision(6) << getRuntime(&end, &start)/1000.0 << " miliseconds" << std::endl;
          std::cout << "Time elapsed: " << std::setprecision(3) << getRuntime(&end, &start)/1000000.0 << " seconds" << std::endl;
      
          return 0;
      }
      

      输出:

      Time elapsed: 3000.08 miliseconds
      Time elapsed: 3 seconds
      

      【讨论】:

        猜你喜欢
        • 2020-04-03
        • 1970-01-01
        • 2012-01-26
        • 2023-03-21
        • 1970-01-01
        • 2013-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多