开发者

clock() vs getsystemtime()

开发者 https://www.devze.com 2023-01-31 14:25 出处:网络
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

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 thre开发者_如何学Cad. 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);
    }
  }
}


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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消