System Clock級高精度計時器,支持Window/Linux平臺。輸入參數CPU主頻,該值可從注冊表(Windows)或/proc/cpuinfo(Linux)中獲得。
大道至簡——精度高,抖動大
//
?*****************************************************************************
//
??IA32Timer???version:??1.0????date:?04/26/2006
//
??----------------------------------------------------------------------------
//
??This?class?is?a?wrapper?of?IA32?RDTSC?
//
??(ReaD?Time?Stamp?Counter)?instruction.
//
??It?will?help?you?get?the?interval?time?with
//
??different?level.
//
??----------------------------------------------------------------------------
//
??Copyright?(C)?2006?-?Charles?Zu
//
?*****************************************************************************
//
?????Note:?All?the?classes?the?author?designed?are?leading?with?"Z"
//
??which?is?contradistinguished?form?the?leading?with?"C"?of?MFC
//
?*****************************************************************************
class
?ZIA32Timer

{
public
:
????ZIA32Timer(
double
?ghz)
????:m_startcycle(
0
),?m_ghz(ghz)

????
{
#ifndef?_WIN32
????????m_high?
=
?
0
;
????????m_low?
=
?
0
;
#endif
????}
????
void
?Start()

????
{
#ifdef?_WIN32
????????m_startcycle?
=
?RTSC();
#else
????????RTSC();
????????m_startcycle?
=
?(unsigned?
long
?
long
)?m_high?
*
?(
1
?
<<
?
30
)?
*
?
4
?
+
?m_low;
#endif
????}
#ifdef?_WIN32
????unsigned?__int64?Stop(
int
?unit);
#else
????unsigned?
long
?
long
?Stop(
int
?unit);
#endif
????
static
?
enum
?Unit
{CYCLE,?NS,?US,?MS,?S}
s_unit;

private
:
#ifdef?_WIN32
????unsigned?__int64??m_startcycle;
#else
????unsigned?
long
?
long
?m_startcycle;
????unsigned?
int
?m_high;
????unsigned?
int
?m_low;
#endif
#ifdef?_WIN32
????unsigned?__int64?RTSC();
#else
???
void
?RTSC();
#endif
double
?m_ghz;

}
;

#ifdef?_WIN32
????inline?unsigned?__int64?ZIA32Timer::RTSC()

????
{
????????_asm????_emit?
0x0F
????????_asm????_emit?
0x31
????}
#else
????inline?
void
?ZIA32Timer::RTSC()

????
{
????????asm(
"
rdtsc;?movl?%%edx,%0;?movl?%%eax,%1
"
???
//
?Read?cycle?counter
????????????:?
"
=r
"
?(m_high),?
"
=r
"
?(m_low)????????????????????????????????????

????????????:?
/**/
/*
?No?input?
*/
?????????????????????????????
????????????:?
"
%edx
"
,?
"
%eax
"
);
????}
#endif
#ifdef?_WIN32
????inline?unsigned?__int64?ZIA32Timer::Stop(
int
?unit)

????
{
????????
switch
(unit)

????????
{
????????
case
?CYCLE:
????????????
return
?(unsigned?__int64)(RTSC()?
-
?m_startcycle);
????????
break
;

????????
case
?NS:
????????????
return
?(unsigned?__int64)((RTSC()?
-
?m_startcycle)?
/
?m_ghz);
????????
break
;

????????
case
?US:
????????????
return
?(unsigned?__int64)((RTSC()?
-
?m_startcycle)?
/
?m_ghz?
/
?
1000
);
????????
break
;

????????
case
?MS:
????????????
return
?(unsigned?__int64)((RTSC()?
-
?m_startcycle)?
/
?m_ghz?
/
?
1000000
);
????????
break
;

????????
case
?S:
????????????
return
?(unsigned?__int64)((RTSC()?
-
?m_startcycle)?
/
?m_ghz?
/
?
1000000000
);
????????
break
;

????????
default
:
????????????
break
;
????????}
????????
return
?
0
;
????}
#else
????inline?unsigned?
long
?
long
?ZIA32Timer::Stop(
int
?unit)

????
{
????????unsigned?
long
?
long
?stoppiont;
????????RTSC();
????????stoppiont?
=
?(((unsigned?
long
?
long
)m_high)?
<<
?
32
)?
+
?m_low;
????????
????????
switch
(unit)

????????
{
????????
case
?CYCLE:
????????????
return
?(unsigned?
long
?
long
)(stoppiont?
-
?m_startcycle);
????????????
break
;

????????
case
?NS:
????????????
return
?(unsigned?
long
?
long
)((stoppiont?
-
?m_startcycle)?
/
?m_ghz);
????????????
break
;

????????
case
?US:
????????????
return
?(unsigned?
long
?
long
)((stoppiont?
-
?m_startcycle)?
/
?m_ghz?
/
?
1000
);
????????????
break
;

????????
case
?MS:
????????????
return
?(unsigned?
long
?
long
)((stoppiont?
-
?m_startcycle)?
/
?m_ghz?
/
?
1000000
);
????????????
break
;

????????
case
?S:
????????????
return
?(unsigned?
long
?
long
)((stoppiont?
-
?m_startcycle)?
/
?m_ghz?
/
?
1000000000
);
????????????
break
;

????????
default
:
????????????
break
;
????????}
????????
return
?
0
;
????}
#endif
下邊給個測試程序,由于我的CPU主頻為3GHZ,所以寫了hard code
#include?<stdio.h>
#ifdef?_WIN32
#include?<windows.h>
#else
#include?<unistd.h>
#endif

#include?"IA32Timer.h"

void?MySleep()


{
#ifdef?_WIN32
//?????Sleep(1);
?????Sleep(10);
//?????Sleep(100);
//?????Sleep(1000);
#else
????usleep(100?*?1000);
#endif
}

int?main(int?argc,?char**?argv)


{
????ZIA32Timer?ztimer(3);?//the?arg?is?the?GHZ?of?your?CPU

#ifdef?_WIN32
unsigned?__int64?interval;
#else
unsigned?long?long?interval;
#endif

????ztimer.Start();
????MySleep();
????interval?=?ztimer.Stop(ZIA32Timer::CYCLE);
????fprintf(stdout,?"interval?=?%u?(cycle)\n",?interval);

????ztimer.Start();
????MySleep();
????interval?=?ztimer.Stop(ZIA32Timer::NS);
????fprintf(stdout,?"interval?=?%u?(ns)\n",?interval);

????ztimer.Start();
????MySleep();
????interval?=?ztimer.Stop(ZIA32Timer::US);
????fprintf(stdout,?"interval?=?%u?(us)\n",?interval);

????ztimer.Start();
????MySleep();
????interval?=?ztimer.Stop(ZIA32Timer::MS);
????fprintf(stdout,?"interval?=?%u?(ms)\n",?interval);

????ztimer.Start();
????MySleep();
????interval?=?ztimer.Stop(ZIA32Timer::S);
????fprintf(stdout,?"interval?=?%u?(s)\n",?interval);

????return?0;
}
參考了高人的匯編實現,自己整理,貼出來,希望對你有啟示
posted on 2006-11-28 14:49
Charles 閱讀(1743)
評論(4) 編輯 收藏 引用 所屬分類:
Helper Utility