我开发了一个用于计算多线程的类,并且线程只使用该类的一个实例。另外,我想通过从另一个线程迭代这个类的容器来测量计算的持续时间。该应用程序是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);
}
}
}
答案 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有一些可以在多个平台上运行的时间函数。