参考了网上的代码,增加了自己的一点点注释,希望大家会有收获。
LONGLONG GetFrequency(DWORD sleepTime) //获取CPU主频
{
DWORD low1 = 0, high1 = 0, low2 = 0, high2 = 0;
LARGE_INTEGER fq,st,ed;
/*在定时前应该先调用QueryPerformanceFrequency()函数获得机器内部计时器的时钟频率。接着在
需要严格计时的事件发生前和发生之后分别调用QueryPerformanceCounter(),利用两次获得的技术
之差和时钟的频率,就可以计算出时间经历的精确时间。*/
::QueryPerformanceFrequency(&fq); //精确计时(返回硬件支持的高精度计数器的频率)
::QueryPerformanceCounter(&st); //获得起始时间
__asm{ //获得当前CPU的时间数
rdtsc
mov low1, eax
mov high1, edx
}
::Sleep(sleepTime); //将线程挂起片刻
::QueryPerformanceCounter(&ed); //获得结束时间
__asm{
rdtsc //读取CPU的时间戳计数器
mov low2, eax
mov high2, edx
}
//将CPU得时间周期数转化成64位整数
LONGLONG begin = (LONGLONG)high1<<32 | low1;
LONGLONG end = (LONGLONG)high2<<32 | low2;
//将两次获得的CPU时间周期数除以间隔时间,即得到CPU的频率
//由于windows的Sleep函数有大约15毫秒的误差,故以windows的精确计时为准
return (end - begin)*fq.QuadPart/(ed.QuadPart-st.QuadPart);
}