时钟() 与 getsystemtime()

发布于 2024-10-08 11:16:19 字数 1075 浏览 3 评论 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);
    }
  }
}

I developed a class for calculations on multithreads and only one instance of this class is used by a thread. Also I want to measure the duration of calculations by iterating over a container of this class from another thread. The application is win32. The thing is I have read QueryPerformanceCounter is useful when comparing the measuremnts on a single thread. Because I can not use it my problem, I think of clock() or GetSystemTime(). It is sad that both methods have a 'resolution' of milliseconds (since CLOCKS_PER_SEC is 1000 on win32). Which method should I use or to generalize, is there a better option for me?
As a rule I have to take the measurements outside the working thread.
Here is some code as an example.

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);
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅唱ヾ落雨殇 2024-10-15 11:16:19

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

我建议阅读“游戏计时和多核处理器”< /a>.

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

QueryPerformanceCounter is fine for multithreaded applications. The processor instruction that may be used (rdtsc) can potentially provide invalid results when called on different processors.

I recommend reading "Game Timing and Multicore Processors".

For your specific application, the problem it appears you are trying to solve is using a timeout on some potentially long-running threads. The proper solution to this would be to use the WaitForMultipleObjects function with a timeout value. If the time expires, then you can terminate any threads that are still running - ideally by setting a flag that each thread checks, but TerminateThread may be suitable.

伤感在游骋 2024-10-15 11:16:19

两种方法的精度均为毫秒

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

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

both methods have a precision of milliseconds

They don't. They have a resolution of a millisecond, the precision is far worse. Most machines increment the value only at intervals of 15.625 msec. That's a heckofalot of CPU cycles, usually not good enough to get any reliable indicator of code efficiency.

QPF does much better, no idea why you couldn't use it. A profiler is a the standard tool to measure code efficiency. Beats taking dependencies you don't want.

伤痕我心 2024-10-15 11:16:19

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

QueryPerformanceCounter should give you the best precision, but there is issues when the function get run on different processors (you get a different result for each processor). So when running in a thread you will experience shifts when the thread switch processor. To solve this you can set processor affinity for the thread that measures time.

苏璃陌 2024-10-15 11:16:19

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

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

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

GetSystemTime gets an absolute time, clock is a relative time but both measure elapsed time, not CPU time related to the actual thread/process.

Of course clock() is more portable. Having said that I use clock_gettime on Linux because I can get both elapsed and thread CPU time with that call.

boost has some time functions that you could use that will run on multiple platforms if you want platform independent code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文