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 阅读(1729)
评论(4) 编辑 收藏 引用 所属分类:
Helper Utility