0

我开发了一个用于多线程计算的类,线程只使用这个类的一个实例。此外,我想通过从另一个线程迭代此类的容器来测量计算的持续时间。应用程序是win32。事情是我读过 QueryPerformanceCounter 在比较单个线程上的测量值时很有用。因为我的问题不能使用它,所以我想到了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

4 回答 4

3

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

我推荐阅读“游戏计时和多核处理器”

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

于 2010-12-22T10:37:49.597 回答
1

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

于 2010-12-22T11:56:46.703 回答
1

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

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

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

于 2010-12-22T10:38:11.173 回答
0

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

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

boost 有一些时间函数,如果你想要独立于平台的代码,你可以使用这些函数在多个平台上运行。

于 2010-12-22T10:31:48.540 回答