获取CPU执行所耗时钟周期的函数
unsigned longlong GetCPUTickCount(){
unsigned long high32=0, low32=0;
#ifdef WIN32 // WIN32
_asm
{
RDTSC;
mov high32,ebx;
mov low32,eax;
}
#else
__asm__ ("RDTSC" : "=a"(low32),"=d"(high32));
#endif
unsigned longlong counter = high32;
counter = (counter<<32) + low32;
return counter;
}
unsigned long high32=0, low32=0;
#ifdef WIN32 // WIN32
_asm
{
RDTSC;
mov high32,ebx;
mov low32,eax;
}
#else
__asm__ ("RDTSC" : "=a"(low32),"=d"(high32));
#endif
unsigned longlong counter = high32;
counter = (counter<<32) + low32;
return counter;
}
//说明:RDTSC (就是ReaD TimeStamp Count) 其精度可以达到ns(纳秒)级别。(准确地说,其精度是1/F,F为你的CPU的时钟频率,这也是极限精度了) //备注:RDTSC指令的机器码为 0x0F 0x31 inline __int64 RDTSC() { __int64 TimeStamp; unsigned long highDword; unsigned long lowDword; __asm { rdtsc; //也可以如下这样直接嵌入机器码 //_emit 0x0F; //_emit 0x31; mov highDword,ebx; mov lowDword,eax; } TimeStamp = highDword; TimeStamp <<= 32; TimeStamp |= lowDword; return TimeStamp; }
RDTSC汇编指令用于程序的精确定时。原理是CPU从上电开始,其内部一个64位计数器就会记录下CPU所经过的周期数,RDTSC指令可以读取该计数器到寄存器EDX:EAX中。理论上计数精度可以达到纳秒级别。
不过在多核CPU平台上使用时发现,两个CPU核的内部计数器不同步。如果程序两次读取这个计数器的时候恰好被轮换到不同的核上,那么用来计时就会有比较大的误差。
解决方法可以采用设定线程亲核性的方法。函数SetThreadAffinityMask可以指定某线程只在某些核上运行(由第二个参数设定,每个位代表一个核)。例如,在需要调用RDTSC的那个线程里执行SetThreadAffinityMask(GetCurrentThread(), 0x00000001);就能保证该线程只在第一个核上运行,不会因为两个核的RDTSC计数器不同步而造成计时误差。
posted on 2009-11-26 18:17 Sunwayking 阅读(1535) 评论(0) 编辑 收藏 举报