bsr*_*uth 4 udp directsound windows-vista windows-7
有问题的软件是本机C++/MFC应用程序,它通过UDP接收大量数据,然后处理数据以进行显示,声音输出和写入磁盘等.当应用程序的CHM帮助文档从其帮助菜单启动时,我第一次遇到问题,然后在从硬件收集数据时单击帮助文档.为了复制它,使用AutoHotkey脚本在应用程序运行时快速单击帮助文档.一旦系统发生任何声音,我就开始收到错误.
如果我完全禁用声卡,一切都处理正常,没有错误,但声音输出明显禁用.但是,如果我有声音播放(在这个应用程序中,一个不同的应用程序,甚至只是消息框中的蜂鸣声)我得到数千个丢弃的数据包(我们知道这是因为每个数据包都有时间戳).作为第二个测试,我根本没有使用我的应用程序,只是使用Wireshark来监视来自硬件的传入数据包.果然,无论何时在Windows中播放声音,我们都丢弃了数据包.实际上,声音甚至不必主动播放以引起错误.如果我只是创建一个缓冲区(使用DirectSound8)并且从不开始播放,我仍然会遇到这些错误.
这种情况发生在具有多种网卡组合(光纤和RJ45)和声卡(集成卡和单独卡)的多台PC上.我还为每个NIC和声卡尝试了不同的驱动程序版本.所有测试都在Windows 7 32位上进行.由于我的应用程序使用DirectSound音频,我尝试了不同的CooperativeLevels(正常操作是DSSCL_PRIORITY)没有成功.
在这一点上,我非常确信它与我的应用程序无关,并且想知道在我开始与硬件供应商和/或微软打交道之前是否有人知道是什么原因导致了这个问题.
事实证明,这种行为是设计的.Windows Vista及更高版本实现了一种称为多媒体类调度程序服务(MMCSS)的功能,旨在使所有多媒体播放尽可能顺畅.由于多媒体播放依赖于硬件中断以确保流畅播放,因此任何竞争中断都会导致问题.主要硬件中断源之一是网络流量.因此,当程序在MMCSS下运行时,Microsoft决定限制网络流量.
我想这是一个大不了回到2007年,当Vista中走了出来,但我错过了.Mark Russinovich(感谢ypnos)撰写了一篇描述MMCSS的文章.似乎我的整个问题归结为:
由于标准以太网帧大小约为1500字节,因此每秒10,000个数据包的限制等于最大吞吐量约为15MB/s.100Mb网络最多可以处理12MB/s,因此如果您的系统位于100Mb网络上,您通常不会看到任何减速.但是,如果您拥有1Gb网络基础架构,并且发送系统和Vista接收系统都具有1Gb网络适配器,您将看到吞吐量下降到大约15%.此外,NDIS限制代码中存在一个不幸的错误,如果您有多个NIC,它会放大限制.例如,如果您的系统同时具有无线和有线适配器,则NDIS每秒最多可处理8000个数据包,并且使用三个适配器时,每秒最多可处理6000个数据包.每秒6000个数据包等于9MB/s,即使在100Mb网络上也是可见的限制.
我还没有验证Windows 7或Vista SP1中是否仍然存在多个适配器错误,但是如果遇到问题则需要查找.
从对Russinovich帖子的评论中,我发现Vista SP1引入了一些注册表设置,允许用户调整MMCSS对Windows的影响.特别是NetworkThrottlingIndex键.
我的问题的解决方案是通过将HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\NetworkThrottlingIndex密钥设置为0xFFFFFFFF然后重新启动来完全禁用网络限制.这完全禁用了MMCSS的网络限制部分.我曾尝试过简单地提升值70,但在完全禁用它之前它并没有停止导致错误.
到目前为止,我还没有看到这种变化对其他多媒体应用程序(我自己的应用程序的视频捕获和音频输出部分)的任何不利影响.如果有变化,我会在这里报告.