提高模块通信速度

     每个模块使用一个线程,以非阻塞方式运作,作为通信基础。由于Windows线程问题,在空循环时,100%消耗资源和时间,造成非阻塞应用效率下降,目前采用的是Sleep(1)或WaitForSingleObject(hEvent, 1),必须有1ms的延时才能通过,当多个模块(线程)(链路)同时运作时,感到问题严重,比如播放视频,每秒30帧,则有30ms延时,什么都不做,就感到了迟钝,延时和资源消耗不可小觑。

怎样取消这1ms延时,在Windods上是做不到的。非阻塞是为提高线程效率(绕开事件消息系统,或某些程序结构这样效率高,比如判断标志再处理等),因为这1ms,却降低了效率。现在寄托在阻塞方式上,是否会小于1ms,有必要编一个测试程序,通过按下按钮,到线程响应时间。

Windods最高定时精度为1ms,无法准确测出1ms内的精度,好在系统提高了QueryPerformanceFrequency,和QueryPerformanceCounter才可高速测试。测试分为阻塞2种,非阻塞2种,结果如下:

1. WaitForSingleObject(hEvent, 1); 非阻塞延时1ms

    延时为 388us - 15388us = 0.388ms - 15.388ms,十分不稳定,延时是大致的,最大延时为15.388ms。

2. Sleep(1); 非阻塞延时1ms

    延时为 388us - 15388us = 0.388ms - 15.388ms,十分不稳定,延时是大致的,最大延时为15.388ms。

3. WaitForSingleObject(pThread->hEvent, INFINITE); 阻塞等待事件信号

    延时为 4us - 30us = 0.004ms - 0.030ms,不稳定,4us为信号相应时间,30us - 4us = 26us 为线程调度时间(大致),最大延时为30us。

4. GetMessage(&msg, NULL, 0, 0); 阻塞等待事件消息

    延时为 10us - 40us = 0.010ms - 0.040ms,不稳定,10us为消息泵时间,40us - 10us = 30us 为消息分派时间,最大延时为40us。

总结:第1,2不可取,因为加入了延时,每个线程延时竟可达15.388ms(35%几率)。第3最小,属于单事件信号,第4略大,因为要经过消息传递、泵送、分派,有一定延误。如果按非阻塞延时1ms,可提速 = 1ms / 0.030ms = 33.33倍。第4可针对多路事件信号。   

备注:另一个有趣的实验是线程循环不阻塞,不延时,加了不少判断,结果还是0us,以us为单位测不出延时,估计是几个机器周期,可见非阻塞线程的执行速度之高。

 

posted @ 2017-03-23 14:26  hbg200  阅读(142)  评论(0编辑  收藏  举报