不太精准的时钟
目前,我们的游戏的同步是依赖机器时钟做预测的。这种做法的前提是,client 的机器和 server 的机器的时钟走速必须相同。这样,当我们把时刻校对了以后,可以不通过网络就可以知道时间信息。即,每个通过网络包传送过来的事件已经发生了多久。这只需要发送方为事件打上时间戳,然后接收方以自己的时候为准求出时间差即可。
我原以为,在 client 不作弊的情况下,只需要登陆校对一次时间即可。而我们的服务器组每台机器也只需要在互相握手的时候校对一次时间,然后各自依靠自己机器上的时钟就可以了。今天发生的事情让我对 PC 的时钟准确度产生了怀疑。
我们以一台 freebsd 系统的机器为基准对时服务器,其他机器连上去获取时间。对时服务的程序用 clock_gettime 获取纳秒级时间,折算成 0.05s 的最小单位供其他程序使用。今天实际测试,发现,这台对时服务器的时钟比我用的 PC (windows xp 平台) 大约每 20 分钟会快上 0.1s 。这误差也太大了点吧。
那一天岂不是会快上 6,7 秒?看来不能忽略时钟不一致的情况,保持半小时一次的对时是有必要的。
ps. 另外我怀疑是 freebsd 的问题,打算周一再仔细研究一下。
5月22日 补 周一来上班,跟同事讨论了一下。首先可能是自己的问题。我的 windows client 测试时间的时候用的函数是 clock() 。我错误理解了这个函数的含义。按标准 clock() 应该返回的是程序运行时间量,即当前进程占用系统时间的量。所以应该换成 windows 的 api GetTickCount 。不过实际测试,没有差别,或许 Windows 下定义不太一样。
而后,换了一台 freebsd 的服务器,时间基本正常了。
另外,Windows 下 QueryPerformanceCounter 是不可用的,这个根据 MSDN 的文档猜测,有可能是用 TSC 实现的。在多核和变频时代,TSC 几乎不可能取到准确的时间。
freebsd 上,使用 TSC 获取时间的优先级最低,现在一般使用 ACPI 获取时钟。在 Windows 上没有找到对应的手段。
Comments
Posted by: iashao | (10) June 10, 2009 10:42 AM
Posted by: anonymous | (9) December 30, 2007 06:45 PM
Posted by: wdq4587 | (8) May 30, 2007 06:02 PM
Posted by: Cloud | (7) July 2, 2006 03:54 AM
Posted by: TripleX | (6) July 1, 2006 11:53 PM
Posted by: ro4tub | (5) May 24, 2006 07:15 PM
Posted by: Cloud | (4) May 21, 2006 10:31 PM
Posted by: puzzy | (3) May 21, 2006 09:08 PM
Posted by: Felix | (2) May 21, 2006 08:17 PM
Posted by: Atry | (1) May 20, 2006 11:14 AM