2013-01-10 77 views
4

如何在C++中精確地測量C++中的某些內容?以高精度在C++中測量時間

這是我的C#代碼

var elapsedMilliseconds = (double)(sw.ElapsedTicks * 1000L)/Stopwatch.Frequency; 

我使用Visual Studio 2010中

+0

只是好奇,爲什麼不在'Stopwatch'財產使用build ['ElapsedMilliseconds'](http://msdn.microsoft.com/en-us/library/system.diagnostics .stopwatch.elapsedmilliseconds.aspx)在C#中? – NominSim

+0

此鏈接是否有幫助:[如何在Windows上使用C++進行高分辨率計時?](http://cplus.about.com/od/howtodothingsi2/a/timing.htm)? –

回答

14

C#中的秒錶類是基於這兩個Win32 API調用,您可以從C/C致電++ :

調用第一個函數並將其除以第二個函數,以秒爲單位獲得一個值。

例子:

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)或硬件抽象層(HAL)中的錯誤,您可以在不同的處理器 上獲得不同的結果。要爲線程指定處理器關聯, 使用SetThreadAffinityMask函數。

您可能會感興趣這更多:System.Diagnostics.Stopwatch returns negative numbers in Elapsed... properties

注意,秒錶類倒在GetTickCount的,如果上述兩個API不可用或返回故障代碼。這可能只是爲了保持與Windows 9x的兼容性;我在現代PC上使用這些API沒有遇到任何問題。但是,GetTickCount不會達到你想要的精度。

+0

我相信'QueryPerformanceCounter'相當於'StopWatch.GetTimestamp',而'QueryPerformanceFrequency'相當於'StopWatch.Frequency'。 – Matthew

0

檢查:How to get system time in C++?

也可以使用的GetTickCount其中: 檢索,因爲這個系統被啓動,高達49.7天即所經過的毫秒數。

+1

GetTickCount不會具有提問者想要的精度;秒錶班更好。 –

0

使用QueryPerformanceFrequency和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所花費的時間。

0

秒錶級是圍繞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; 
0

我需要一個更具體的測量和發現的一個。 Thx爲其他答案。他們都很好。有了這個答案,如果需要,我可以輕鬆切換到微秒。

當然,我會接受詹姆斯約翰斯頓的答案作爲正確的答案,因爲偉大的解釋和人們的反饋。

THX所有

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