程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> VC++ >> VC++通過匯編獲取代碼運行時間

VC++通過匯編獲取代碼運行時間

編輯:VC++

     如何獲得程序或者一段代碼運行的時間?你可能說有專門的程序測試工具,確實,不過你也可以在程序中嵌入匯編代碼來實現。

     在Pentium的指令系統中有一條指令可以獲得CPU內部64位計數器的值,我們可以通過代碼兩次獲取該計數器的值而獲得程序或代碼運行的時鐘周期數,進而通過你的cpu的頻率算出一個時鐘周期的時間,從而算出程序運行的確切時間。

    我們通過指令TDSIC來獲得cpu內部計數器的值,指令TDSIC返回值放在EDX:EAX中,其中EDX中存放64位寄存器中高32位的值,EAX存放第32位的值.

    下面看看實現的代碼:


//用匯編實現獲取一段代碼運行的時間

#include<iostream>

using namespace std;

void GetClockNumber (long high, long low);
void GetRunTime();
 
int main()
{      
 
 long HighStart,LowStart,HighEnd,LowEnd;
 long numhigh,numlow;
 //獲取代碼運行開始時cpu內部計數器的值
 __asm             
 {
  RDTSC
  mov HighStart, edx
  mov LowStart, eax
 }
 for(int i= 0; i<100000; i++ )
 {
             for(int i= 0; i<100000; i++ )
      {
      
      }
 }


 //獲取代碼結束時cpu內部計數器的值,並減去初值
        __asm
 {
  RDTSC
  mov HighEnd, edx
  Mov LowEnd,  eax
  ;獲取兩次計數器值得差
  sub eax,  LowStart
  cmp    eax,  0       ; 如果低32的差為負則求返,因為第二次取得永遠比第一次的大
  jg     L1
  neg     eax
  jmp     L2
            L1: mov numlow,  eax
            L2: sbb edx,  HighStart
  mov numhigh, edx
 
 }
        //把兩個計數器值之差放在一個64位的整形變量中
        //先把高32位左移32位放在64的整形變量中,然後再加上低32位
 __int64  timer =(numhigh<<32) + numlow;
         //輸出代碼段運行的時鐘周期數
         //以頻率1.1Gcpu為例,如果換計算機把其中的1.1改乘其它即可,因為相信大家的cpu都應該在1G以上  ^_^
 cout<< (double) (timer /1.1/1000000000) << endl;
 return 0;
}

     這樣通過一條簡單的匯編指令就可以獲得程序或一段代碼的大概時間,不過並不能得到運行的確切時間,因為即使去掉中間的循環,程序也會有個運行時間,

因為在第一次取得計數器的值後,有兩條匯編指令mov HighStart, edx       mov LowStart, eax這兩條指令當然也有運行時間 ,當然你可以減去這兩條指令的運行時間(在1.1G的機子上是3e-8s),這樣會更精確一點。

    如果你要確切知道程序的運行時間,專業的測試軟件肯定會更好一點,不過好像一般沒有必要獲取除非專門的要求的程序。

    不過能DIY一個也是不錯的,不管有沒有,最起碼你可以學到在VC++中如何嵌入匯編代碼以及如何使用32位的寄存器,其實和16位的寄存器一樣使用,將來64的也應該一樣,只不過位數不同罷了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved