c語言計時納秒 如何利用rdtsc計算納秒級的時間

2021-10-16 13:29:44 字數 1558 閱讀 1721

從奔騰(penium)系列開始,intel

x86 處理器中增加了乙個64位的時間戳暫存器(tsc),每個經過乙個時鐘週期,該暫存器加1;機器重啟時,該暫存器將清空。

現在的處理器其主頻都在1g以上,也就是說其時鐘週期是納秒級的(1秒/1000000000=1納秒)。

那該暫存器會不會溢位呢?我們可以計算一下,假設機器的主頻是3gmhz,

也就是說1秒鐘包含3,000,000,000個時鐘週期,每個時鐘週期為0.33333納秒,則64位暫存器溢位所需要的時間為:

2^64 / 3000000000 ≈

6148914691 秒 ≈71168天 ≈ 195年

因此tsc溢位基本是不可能的了。

rdtsc 是一條機器指令用於讀取該時間戳暫存器中的值。

下面的程式就是通過在c語言呼叫rdtsc來得到時鐘週期:

#include

#include

__int64

__declspec(naked) read_time_stamp_counter()

__asm

cpuid; __asm rdtsc;

__asm ret;

int main()

{ float ticks_1, ticks_2;

unsigned int i,j=0;

unsigned int loop = 4000000000;

ticks_1 = (float)read_time_stamp_counter();

for(i=0;i

j++;

j++;

ticks_2

= (float)read_time_stamp_counter();

printf("\ntotal

ticks is : %f\n", ticks_2-ticks_1);

printf("\ntotal ticks per loop is : %f\n",

(ticks_2-ticks_1)/loop);

printf("\ntotal time is %f seconds\n", (ticks_2 -

ticks_1)/3300000000);

return 1;

說明:(1)

子函式read_time_stamp_counter()並沒有明確的指定返回值,為什麼程式中仍然可以得到正確的值?原因在於指令rdtsc將時間戳的放在edx:eax中,而這與c語言子函式的返回值的存放位址是一致的(參見

(2) 子函式read_time_stamp_counter()的定義中加入__deslspec(naked),

是避免編譯器在編譯該函式時新增其他的語句,通過下面的c**的反彙編可以看到__deslspec(naked)的作用:

(3) 執行程式的計算機的cpu是3.3ghz。

(4) 程式的執行結果如下, 從中可以看出,

每個迴圈所耗費的時鐘週期是12左右,(注意時鐘週期不同於指令週期,指令週期是指執行一條指令所花費的時間,可以用時鐘週期表示,一般乙個指令週期等於1個或多個時鐘週期);根據時鐘週期總數和cpu的主頻,我們可以計算出整個迴圈所花費的時間大約是14.83秒。

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

queryperformancecounter獲得cpu執行計數值 精確的時間計量方法在某些應用程式中是非常重要的。常用的 windows api 方法 gettickcount 返回系統啟動後經過的毫秒數。另一方面,gettickcount 函式僅有 1ms 的分辨精度,很不精確。故而,我們要另外...

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

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

C語言如何利用陣列儲存「變數」

背景解決方法 說明眾所周知,陣列僅能儲存常量資料,包括數字常量 字元常量 字串常量。但在實際應用中,可能會遇到需要按需修改陣列中資料值的需求,此時又應該如何解決呢?通過一段時間的測試驗證,解決了專案中的該需求,於是便產生了本篇文章,也是本人的第一篇技術部落格。如果有不足或錯誤之處,還望讀者可以不吝賜...