取CPU时间,精确到ms级。类似gettickcount

delphi 函数如下:

//取系统时间,类似于 GetTickCount ,但精确度高,精确到1ms。且取出时间为8个字节整型
class function TSwitchMacList.getSysTickCount64() : int64;
{$j+} //局部静态变量
const
  TicksPerSecond : int64 = 0;
{$j-}
var
  Tick,Seconds,LeftPart,MillSeconds,Ret : int64;
begin
  if TicksPerSecond = 0 then    QueryPerformanceFrequency(TicksPerSecond);
  QueryPerformanceCounter(Tick);
  Seconds     := Tick div TicksPerSecond;
  LeftPart    := Tick - (TicksPerSecond*Seconds);
  MillSeconds := LeftPart*1000 div TicksPerSecond;
  Ret         := Seconds*1000+MillSeconds;
  result := Ret;
end;

 

C函数如下:

__int64 GetSysTickCount64()
{
    static LARGE_INTEGER TicksPerSecond = {0};
    LARGE_INTEGER Tick;

    if(!TicksPerSecond.QuadPart)
    {
        QueryPerformanceFrequency(&TicksPerSecond);
    }

    QueryPerformanceCounter(&Tick);

    __int64 Seconds = Tick.QuadPart/TicksPerSecond.QuadPart;
    __int64 LeftPart = Tick.QuadPart - (TicksPerSecond.QuadPart*Seconds);
    __int64 MillSeconds = LeftPart*1000/TicksPerSecond.QuadPart;
    __int64 Ret = Seconds*1000+MillSeconds;
//    __ASSERT(Ret>0);
    return Ret;
};

 

源贴地址:

http://huyuguang1976.spaces.live.com/blog/cns!2A9E272E3C33AFF1!182.entry

 

源贴内容:

 

2月25日
高精度 GetTickCount64

 

32位的GetTickCount有2个缺陷,第一是49天之后uint32就不够用了,这对于运行于长时间不关机的服务器,或者总是处于休眠模式下的笔记本上的程序来说,是无法忍受的缺陷。其次是GetTickCount的精度有限,MSDN文档中叙述说精度取决于系统timer,一般来说,NT家族的操作系统的系统timer是10ms或20ms。

vista支持一个新的函数叫GetTickCount64,这个函数返回int64的毫秒数,从而避开了49天之后uint32不够用的问题。但这个函数仅能在vista或者win2k8上使用。

为此,写一个自己的高精度函数是有必要的。

第一版代码如下:

int64 HELPER_API GetSysTickCount64()
{
     static LARGE_INTEGER TicksPerSecond = {0};
    LARGE_INTEGER Tick;

    if(!TicksPerSecond.QuadPart)
    {
        QueryPerformanceFrequency(&TicksPerSecond);
    }

    QueryPerformanceCounter(&Tick);
    return Tick.QuadPart *1000/TicksPerSecond.QuadPart;

}

这个函数逻辑很简单,首先获取每秒cpu的时钟周期数,然后获取开机以来cpu的时钟数,然后一除即可得到开机以来的毫秒数。

但这个函数有一个隐秘的错误在于,Tick.QuadPart*1000有可能导致int64溢出,实际上在我的一台运行了不到100天的服务器上的确发生了这种事情。cpu越来越快,服务器越来越稳定,从而Tick的值非常大,再乘以1000,溢出也就不奇怪了。

因此第二版代码如下:

int64 HELPER_API GetSysTickCount64()
{
    static LARGE_INTEGER TicksPerSecond = {0};
    LARGE_INTEGER Tick;

    if(!TicksPerSecond.QuadPart)
    {
        QueryPerformanceFrequency(&TicksPerSecond);
    }

    QueryPerformanceCounter(&Tick);

    int64 Seconds = Tick.QuadPart/TicksPerSecond.QuadPart;
    int64 LeftPart = Tick.QuadPart - (TicksPerSecond.QuadPart*Seconds);
    int64 MillSeconds = LeftPart*1000/TicksPerSecond.QuadPart;
    int64 Ret = Seconds*1000+MillSeconds;
    _ASSERT(Ret>0);
    return Ret;
}

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值