static inline uint64
rdtsc()
{
unsigned int lo, hi;
#ifdef __linux__
/* We cannot use "=A", since this would use %rax on x86_64 */
__asm__ __volatile__ (
"rdtsc"
: "=a" (lo), "=d" (hi)
);
#else
#error "not done yet "
#endif
return (uint64)hi << 32 | lo;
}
uint64 GetCpuFreq()
{
static uint64 freq = 0;
char buf[1024], *p[2];
if (0 != freq) {
return freq;
}
FILE* fp = fopen("/proc/cpuinfo", "rb");
if (fp != NULL) {
while (fgets(buf, sizeof(buf), fp) != NULL) {
if (2==SplitString(buf, ':', p, 2) && 0==strnicmp(p[0], "cpu MHz", 7)) {
double f = strtod(p[1], NULL);
freq = (uint64)(f * 1000000.0);
//printf("freq=%u\n", freq);
break;
}
}
fclose(fp);
}
if (0 == freq) {
freq = CalcCpuFreq();
}
return freq;
}
static uint64
CalcCpuFreq()
{
uint64 t1;
uint64 t2;
t1 = rdtsc();
Sleep(100);
t2 = rdtsc();
return (t2-t1)*10;
}
class CCycleTimer
{
public:
CCycleTimer(bool bStart = false) { Init(bStart); }
~CCycleTimer() {}
void Start(bool bReset = false) {
uint64 i = rdtsc();
Lock();
if (bReset)
m_Elapsed = 0;
m_Start = i;
UnLock();
}
void Stop() {
uint64 i = rdtsc();
Lock();
if (0 != m_Start) {
m_Elapsed += i - m_Start;
m_Start = 0;
}
UnLock();
}
uint64 Peek() {
uint64 n;
Lock();
n = m_Elapsed;
if (0 != m_Start) {
n += rdtsc() - m_Start;
}
UnLock();
return n;
}
bool IsRunning() {
bool b;
Lock();
b = m_Start != 0;
UnLock();
return b;
}
const double Elapsed() { // Returns elapsed time in seconds
return (double)Peek() / m_Freq;
}
const double Elapsedms() { // Returns elapsed time in milliseconds
return ((double)Peek() / m_Freq) * 1000.0;
}
const double Elapsedus() { // Returns elapsed time in microseconds
return ((double)Peek() / m_Freq) * 1000000.0;
}
void Init(bool bStart) {
m_Elapsed = 0;
m_Start = 0;
m_Freq = GetCpuFreq();
if (bStart) {
Start();
}
}
protected:
void Lock() {}
void UnLock() {}
private:
uint64 m_Start, m_Freq, m_Elapsed;
};
class CLocalTimer
{
CCycleTimer& m_timer;
public:
CLocalTimer(CCycleTimer& t) : m_timer(t) { m_timer.Start(); }
~CLocalTimer() { m_timer.Stop(); }
};
rdtsct tricky hack
最新推荐文章于 2020-04-04 11:27:46 发布