关于 高精度性能计数器的频率 和 cpu 频率 不一致问题
/*
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位。
浙公网安备 33010602011771号