rdtsct tricky hack

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(); }
};

你可能感兴趣的:(baidu生活,c++,fp,null,class,timer,linux,file)