/* rdtsc指令, 该指令返回CPU自启动以来的时钟周期数;该时钟周期数,即处理器的时间戳。在CPU通电启动后,首先会重置EDX和EAX,在每个时钟周期上升或下降沿到来时,会自动累计周期数,并被记录到EDX和EAX寄存器中,EDX是高位,EAX是低位。rdtsc指令就是从该寄存器中进行获取的。周期和频率的关系公式:T(周期)=1/f(频率)如CPU频率f为1GHz,则其时钟周期T=1/1GHz秒,意味着每隔T秒,CPU完成一个最基本的动作,并在寄存器中,对周期数加1。故,假设当前时钟周期数为m,则可计算出CPU自启动后,累计运行时间X=m*T高精度性能计数器的频率是不变的,而且比cpu(平均)频率低得多 */#include <iostream> #include <windows.h> using namespace std;#define read_tsc(tsc) \long long tsc; \_asm rdtsc \_asm mov dword ptr[tsc],eax \_asm mov dword ptr[tsc+4],edx#define read_hrpc(pc) \LARGE_INTEGER pc; \QueryPerformanceCounter(&pc);int main() {read_hrpc(pc1);read_tsc(tsc1);cout << "waiting..." << endl;Sleep(1000);read_tsc(tsc2);read_hrpc(pc2);LARGE_INTEGER freq;QueryPerformanceFrequency(&freq);double elapse = (pc2.QuadPart - pc1.QuadPart) / (double)freq.QuadPart;double cpu_freq = (tsc2 - tsc1) / elapse;cout << "perf freq:\t" << freq.QuadPart / 1000.0 / 1000 << "\tMHz" << endl;cout << "cpu freq:\t" << cpu_freq / 1000 / 1000 / 1000 << "\tGHz" << endl;return 0; }
备注:
QueryPerformanceFrequency将获得一个频率Freq,它表示高性能计时器1秒钟的计数次数,也就是说QueryPerformanceCounter获得的时间是一个计数值,其单位是秒。
高性能计时器的精度:在笔者的电脑上,频率Freq为3134267,一个计数的时间是秒,也就是0.319微秒或319纳秒。这也就是高性能计时器的精度。
高性能计时器的归零:QueryPerformanceCounter获得的计数是一个有符号的64位整数。频率Freq为3134267的Windows在连续运行9.3万年后,QueryPerformanceCounter获得的计数才可能归零。
需要注意:并不是所有的电脑都支持QueryPerformanceCounter,返回0不支持。
内联汇编VS 64位 改 32位。