用c++语言测量时间,精度高

本文关键字:精度高 时间 测量 c++ 语言 | 更新日期: 2023-09-27 17:51:16

我如何在c++中像在c#中一样准确地测量一些东西?

这是我的c#代码
var elapsedMilliseconds = (double)(sw.ElapsedTicks * 1000L) / Stopwatch.Frequency;

我使用visual studio 2010。

用c++语言测量时间,精度高

c#中的Stopwatch类基于以下两个Win32 API调用,您可以从C/c++调用它们:

  • QueryPerformanceCounter
  • QueryPerformanceFrequency

调用第一个函数并除以第二个函数得到以秒为单位的值。

的例子:

LARGE_INTEGER freq, start, end;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
// do some long operation here
Sleep(5000);
QueryPerformanceCounter(&end);
// subtract before dividing to improve precision
double durationInSeconds = static_cast<double>(end.QuadPart - start.QuadPart) / freq.QuadPart;

请注意,文档中的以下注释是真实的,应该予以考虑。我个人在VirtualBox虚拟机中观察到这种行为。不同的处理器之间可能存在几十毫秒的差异,从而导致意想不到的结果,例如负持续时间和长于预期的持续时间:

在多处理器计算机上,哪个处理器应该无关紧要调用。但是,在不同的处理器上可以得到不同的结果可能是BIOS (basic input output system)或硬件存在问题抽象层(HAL)。要指定线程的处理器关联,请使用使用SetThreadAffinityMask函数

您可能对以下内容感兴趣:System.Diagnostics.Stopwatch在Elapsed中返回负数…

属性

注意,如果上面两个api不可用或返回失败代码,Stopwatch类会返回GetTickCount。这可能只是为了保持与Windows 9x的兼容性;我自己在现代pc上使用这些api没有遇到任何问题。然而,GetTickCount不会有您想要的精度。

我需要一个更具体的度量,并找到了一个。谢谢你的回答。他们都很好。有了这个答案,如果需要的话,我可以很容易地切换到微秒。

我当然会接受James Johnston的答案,因为他的解释和人们的反馈都很好。

谢谢所有的

int main(int argc, char ** argv)
{
unsigned long long nFreq = GetPerformanceTicksInSecond();
unsigned long long nBefore = GetPerformanceTicks();
timer start1 = timer::start();
CallSomeFunction();
unsigned long long nAfter = GetPerformanceTicks();
const unsigned long long nDiff = nAfter - nBefore;
const unsigned long long nMicroseconds = GetTickMicroseconds(nDiff,nFreq);
cout << "CallSomeFunction() took " << nMicroseconds << " " << time << endl;
return 0;
}
unsigned long long GetPerformanceTicks()
{
    LARGE_INTEGER nValue;
    ::QueryPerformanceCounter(&nValue);
    return nValue.QuadPart;
}
unsigned long long GetPerformanceTicksInSecond()
{
    LARGE_INTEGER nFreq;
    ::QueryPerformanceFrequency(&nFreq);
    return nFreq.QuadPart;
}
double GetTickSeconds(unsigned long long nTicks,unsigned long long nFreq)
{
    return static_cast<double>(nTicks) / static_cast<double>(nFreq);
}
unsigned long long GetTickMilliseconds(unsigned long long nTicks,unsigned long long nFreq)
{
    unsigned long long nTicksInMillisecond = nFreq / 1000;
    return nTicks / nTicksInMillisecond;
}
unsigned long long GetTickMicroseconds(unsigned long long nTicks,unsigned long long nFreq)
{
    unsigned long long nTicksInMicrosecond = nFreq / 1000000;
    return nTicks / nTicksInMicrosecond;
}

检查这个:如何在c++中获得系统时间?

也可以使用GetTickCount:检索自系统启动以来所经过的毫秒数,最多49.7天。

使用queryperformancfrequency和QueryPerformanceCounter API函数

LARGE_INTEGER freq;
::QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;
::QueryPerformanceCounter(&start);
// do some work
::QueryPerformanceCounter(&end);
double const t = double(end.QuadPart - start.QuadPart) / double(freq.QuadPart);

为了提高准确性,您可能需要从结果中减去调用QueryPerformanceCounter所需的时间。

stopwatch类是QueryPerformanceCounter的包装:

uint64_t startTime, endTime;
uint64_t frequency;
QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
QueryPerformanceCounter((LARGE_INTEGER*)&startTime);
//DoStuff
QueryPerformanceCounter((LARGE_INTEGER*)&endTime);
double seconds = (endTime-startTime)/(double) frequency;