clock()vs getsystemtime()

时间:2010-12-22 10:15:36

标签: c++ multithreading time clock measurement

我开发了一个用于计算多线程的类,并且线程只使用该类的一个实例。另外,我想通过从另一个线程迭代这个类的容器来测量计算的持续时间。该应用程序是win32。事情是我已经读过QueryPerformanceCounter在比较单个线程上的measuremnts时很有用。因为我无法使用它我的问题,我想到了clock()或GetSystemTime()。令人遗憾的是,两种方法都具有毫秒级的“分辨率”(因为在win32上CLOCKS_PER_SEC为1000)。我应该使用哪种方法或概括,对我来说有更好的选择吗? 作为一项规则,我必须在工作线程之外进行测量。 以下是一些代码示例。

unsinged long GetCounter()
{
  SYSTEMTIME ww;
  GetSystemTime(&ww);
  return ww.wMilliseconds + 1000 * ww.wSeconds; 
// or
  return clock();
}

class WorkClass
{
  bool is_working;
  unsigned long counter;
  HANDLE threadHandle;
public:
  DoWork()
  {
    threadHandle = GetCurrentThread();
    is_working = true;
    counter = GetCounter();
    // Do some work
    is_working = false;
  }
};

void CheckDurations() // will work on another thread;
{
  for(size_t i =0;i < vector_of_workClass.size(); ++i)
  {
    WorkClass & wc = vector_of_workClass[i];
    if(wc.is_working)
    {
      unsigned long dur = GetCounter() - wc.counter;
      ReportDuration(wc,dur);
      if( dur > someLimitValue)
        TerminateThread(wc.threadHandle);
    }
  }
}

4 个答案:

答案 0 :(得分:3)

QueryPerformanceCounter适用于多线程应用程序。 可能使用的处理器指令(rdtsc)在不同处理器上调用时可能会提供无效结果。

我建议阅读"Game Timing and Multicore Processors"

对于您的特定应用程序,您尝试解决的问题是在某些可能长时间运行的线程上使用超时。对此的正确解决方案是使用具有超时值的WaitForMultipleObjects函数。如果时间到期,那么您可以终止仍在运行的所有线程 - 理想情况下通过设置每个线程检查的标志,但TerminateThread可能是合适的。

答案 1 :(得分:1)

  

两种方法都具有毫秒的精度

他们没有。它们的分辨率是一毫秒,精度要差得多。大多数机器仅以15.625毫秒的间隔递增值。这是CPU周期的混乱,通常不足以获得任何可靠的代码效率指标。

QPF做得更好,不知道为什么你不能使用它。分析器是衡量代码效率的标准工具。打败你不想要的依赖。

答案 2 :(得分:1)

QueryPerformanceCounter应该为您提供最佳精度,但是当函数在不同的处理器上运行时会出现问题(每个处理器会得到不同的结果)。因此,当在线程中运行时,您将在线程切换处理器时遇到转换。要解决此问题,您可以为测量时间的线程设置处理器关联。

答案 3 :(得分:0)

GetSystemTime获取绝对时间,时钟是相对时间,但都是测量经过的时间,而不是与实际线程/进程相关的CPU时间。

当然,clock()更便携。说过我在Linux上使用clock_gettime,因为我可以通过该调用获得经过时间和线程CPU时间。

如果您需要与平台无关的代码,

boost有一些可以在多个平台上运行的时间函数。