C 中的高精度計時方法(納秒級別計時)

2021-05-22 15:13:17 字數 4031 閱讀 6772

queryperformancecounter獲得cpu執行計數值

精確的時間計量方法在某些應用程式中是非常重要的。常用的 windows api 方法 gettickcount() 返回系統啟動後經過的毫秒數。另一方面,gettickcount() 函式僅有 1ms 的分辨精度,很不精確。

故而,我們要另外尋找一種方法來精確測量時間。

win32 api 使用 queryperformancecounter() 和 queryperformancefrequency() 方法支援高精度計時。這些方法,比「標準的」毫秒精度的計時方法如 gettickcount() 之類有高得多的精度。另一方面來說,在 c# 中使用「非託管」的 api 函式會有一定的開銷,但比起使用一點都不精確的 gettickcount() api 函式來說要好得多了。

第乙個函式 queryperformancecounter() 查詢任意時刻高精度計數器的實際值。第二個函式 queryperformancefrequency() 返回高精度計數器每秒的計數值。為了獲得某一**段經歷的時間,你需要獲得**段開始前和結束後這兩個計時時刻的高精度計數器實際值。這兩個值的差指出了**段執行所經歷的時間。

然後通過將差除以每秒計數值(高精度計時器頻率),就可以計算經過的時間了。

duration = (stop - start) / frequency 

經過時間 = (停止時間 - 開始時間) / 頻率

需要關於 queryperformancecounter 和 queryperformancefrequency 的更多資訊,請參閱 msdn 文件。

** 下面的類實現了 queryperformancecounter() 和 queryperformancefrequency() api 函式的功能。

using system; 

using system.runtime.interopservices; 

using system.componentmodel; 

using system.threading;

namespace win32  }

// 開始計時器 

public void start() 

// 停止計時器 

public void stop() 

// 返回計時器經過時間(單位:秒) 

public double duration  } 

} }使用這個類很簡單。只需要建立乙個 hiperftimer 的例項,然後呼叫 start() 開始計時,stop() 停止計時。要獲得經過的時間,呼叫 duration() 函式即可。

參考下面的例子。 hiperftimer pt = new hiperftimer();     // 建立新的 hiperftimer 物件 

pt.start();                             // 啟動計時器 

console.writeline("test/n");            // 需要計時的** 

pt.stop();                              // 停止計時器 

console.writeline("duration: sec/n", 

pt.duration); // 列印需要計時部分**的用時

下面的是該例子在我系統上的輸出。

高精度計時

private void button1_click_1(object sender, eventargs e)

system.diagnostics.stopwatch mywatch = new system.diagnostics.stopwatch();

mywatch.start();

system.threading.thread.sleep(100);

mywatch.stop();

messagebox.show( mywatch.elapsedmilliseconds.tostring() + "毫秒");

當計算時間進入納秒級時,stopwatch(最小精是毫秒) 是無法計時的,還environment.tickcount獲取系統啟動應用程式的毫秒級。對於要求不高,計算時間在毫秒級可以用stopwatc或environment.tickcount。若有計算納秒級的計時就只能使用上面第一種方法。

.net 實現納秒級別計算 

1)建立vc.net 託管類庫

using namespace system;

namespace mltimerdot

//得到計算機啟動到現在的時鐘週期

unsigned __int64 getcyclecount(void)

_asm  _emit 0x0f

_asm  _emit 0x31

//宣告 .net 類

public __gc class mltimer

protected:

uint64 m_startcycle;

uint64 m_overhead;

public:

mltimer(void)

//為了計算更精確取得呼叫乙個 getcyclecount() 的時鐘週期

m_overhead=0;

start();

m_overhead=stop();

//計算停止

uint64 stop(void)

return getcyclecount()-m_startcycle-m_overhead;

//計算開始

void start(void)

m_startcycle=getcyclecount();

__property virtual uint64 get_overhead()

return m_overhead;

2)測試**

//c# 引用後放乙個button 測試

private void button1_click(object sender, system.eventargs e)

mltimerdot.mltimer timer=new mltimerdot.mltimer();

timer.start();

thread.sleep(1000);

uint64 cpuspeed10=(ulong)(timer.stop()/100000); //通過這個可以算出 cpu 的mhz

timer.start();//開始

//測試**(測試宣告乙個datatable 用的時間)

datatable td= new datatable();

uint64 time1=timer.stop();//停止

string s= string.format("cpu . mhz/n宣告 mltimer 類的系統開銷 時鐘週期/n本作業系統開銷 個時鐘週期/n使用 ns",

cpuspeed10/10,cpuspeed10%10,timer.overhead,

time1,

time1*10000/cpuspeed10);

messagebox.show(s);

mltimer 類庫必須使用vc。net 開發,只有vc。net 可以墜入彙編(爽)。

編譯完成可以在任何.net語言下使用(當然也可以封裝成api , 或 com 元件)。

想想以後可以在網頁上顯示:

你本次查詢使用了:***xx 納秒。

是不是很爽^_^,當然還可以進行一些精密的計算,

演示**:

宣告:本源**你可以用於任何用途,不過用於商業程式時請通知本人,謝謝。qq 65423574

高精度納秒計時器

ktimer.h windows graphics programming win32 gdi and directdraw?feng yuan publisher prentice hall ptr first edition december 01,2000 高精度納秒計時器,最後修改 2008...

Delphi高精度計時方法

取毫秒級時間精度 方法一 vart1,t2 int64 r1 int64 begin t1 gettickcount 獲取開始計數 windows api sleep 1000 執行要計時的 t2 gettickcount 獲取結束計數值 r1 t2 t1 取得計時時間,單位毫秒 ms showme...

c納秒級計時器 C 11 計時器!真香

在我們寫程式過程中,有時候需要測試我們的程式語句執行時間的耗時,當前也是有很多的庫提供我們去使用,一直沒有良好的跨平台的庫可以提供出來 而且一般這種 也是由我們程式設計師自己呼叫系統的庫來進行,但是往往會出現精度不足和不支援跨平台等問題 他來了。他來了。他踩著七彩祥雲來了 他 就是c 11中引進bo...