Sunwayking

导航

获取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;
}

 

 

 

 

 
//说明: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  阅读(1509)  评论(0编辑  收藏  举报