由于最新的Windows 8对于WiFi 传输有Latency的要求,最近一直在忙这件事。
MS要求Peer到Peer之间的Lantency要小于几十个毫秒吧。这段时间可以划分为一下这几个部分:
APP-->Driver--(Air)-->Driver in Rx side-->APP in Rx side。
我发现在Receiver这一端,经常会发生Driver Indicate Packet给OS到APP收到这个包,有时候会有大的延时。
因为用的是UDP,理论上应该没有window,sequence number这种概念,OS只要收到一个数据包就应该通知APP。
根据Driver的现状一开始以为可能跟下面这些因素有关:
1.Resource,因为Driver Pre-allocated的一些memory有可能会不够。
2.Disorder,Driver发送IP layer的数据包,有时候存在乱序。
但是Debug,fix了1,2这两个问题,latency还是很大,有几十ms.
终于在下班前想到一点,就是APP本身的问题,APP是一个同事写的,下面简单描述下Rx端的伪代码:
config socket... for(;;){WSARecvFrom(socket,...);...Do something....}
发现Latency其实就在于Do something花费了一段可观的时间。代码的逻辑导致APP需要逐个处理数据包,Do something需要花费大概2ms。也就是说1s最多能handle500个Packet,但是Driver有时在1s内会indicate将近800个Packet给OS。所以导致APP这边存在瓶颈,OS只有等APP处理玩当前数据包,才传下一个给APP。
To fix,就是要尽量缩短Do something暂用的时间。APP的架构需要变一下,用两个Thread,一个只管收,占用时间要短,另一个做Do something的处理。
BTW,介绍下Windows精确计时的方法:
UserMode: QueryPerformanceCounter()/QueryPerformanceFrequency();
KernelMode: KeQueryPerformanceCounter(&PerformanceFrequency);
用上面这几个函数就可以了,具体用法见MSDN。