4

有问题的软件是本机 C++/MFC 应用程序,它通过 UDP 接收大量数据,然后处理数据以进行显示、声音输出和写入磁盘等。当应用程序的 CHM 帮助文档从其帮助菜单启动时,我第一次遇到问题,然后我在从硬件收集数据时单击帮助文档。为了复制这一点,使用 AutoHotkey 脚本在应用程序运行时快速单击帮助文档。一旦系统上出现任何声音,我就开始出错。

如果我完全禁用了声卡,则一切正常,没有错误,尽管声音输出显然被禁用。但是,如果我有声音播放(在这个应用程序中,不同的应用程序,甚至只是来自消息框的哔哔声),我会收到数千个丢弃的数据包(我们知道这一点,因为每个数据包都有时间戳)。作为第二个测试,我根本没有使用我的应用程序,只是使用 Wireshark 来监视来自硬件的传入数据包。果然,每当在 Windows 中播放声音时,我们都会丢包。事实上,声音甚至不必主动播放来导致错误。如果我只是创建一个缓冲区(使用 DirectSound8)并且从不开始播放,我仍然会收到这些错误。

这发生在具有多种网卡(光纤和 RJ45)和声卡(集成卡和独立卡)组合的多台 PC 上。我还为每个 NIC 和声卡尝试了不同的驱动程序版本。所有测试均在 Windows 7 32 位上进行。由于我的应用程序将 DirectSound 用于音频,因此我尝试了不同的 CooperativeLevels(正常操作是 DSSCL_PRIORITY)但没有成功。

在这一点上,我非常确信它与我的应用程序无关,并且想知道在我开始与硬件供应商和/或 Microsoft 打交道之前是否有人知道可能导致此问题的原因。

4

2 回答 2

6

事实证明,这种行为是设计使然。Windows Vista 和更高版本实现了称为多媒体类调度程序服务 (MMCSS)的功能,旨在使所有多媒体播放尽可能流畅。由于多媒体播放依赖于硬件中断来保证流畅的播放,任何竞争性的中断都会导致问题。主要的硬件中断源之一是网络流量。因此,当程序在 MMCSS 下运行时,Microsoft 决定限制网络流量。

我想这在 2007Vista 出现时是一件大事,但我错过了。Mark Russinovich 有一篇文章(感谢ypnos描述 MMCSS。看来我的整个问题归结为:

因为标准以太网帧大小约为 1500 字节,所以每秒 10,000 个数据包的限制等于大约 15MB/s 的最大吞吐量。100Mb 网络最多可以处理 12MB/s,因此如果您的系统在 100Mb 网络上,您通常不会看到任何减速。但是,如果您有一个 1Gb 的网络基础架构,并且发送系统和您的 Vista 接收系统都有 1Gb 网络适配器,您会看到吞吐量下降到大约 15%。此外,如果您有多个 NIC,NDIS 限制代码中有一个不幸的错误会放大限制。例如,如果您的系统同时具有无线和有线适配器,NDIS 每秒最多可以处理 8000 个数据包,而使用三个适配器,它每秒最多可以处理 6000 个数据包。每秒 6000 个数据包等于 9MB/s,

我尚未验证 Windows 7 或 Vista SP1 中是否仍然存在多适配器错误,但如果您遇到问题,则需要寻找它。

从 Russinovich 帖子的评论中,我发现 Vista SP1 引入了一些注册表设置,允许调整 MMCSS 如何影响 Windows。特别是NetworkThrottlingIndex 键

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\NetworkThrottlingIndex我的问题的解决方案是通过将密钥设置为0xFFFFFFFF然后重新启动来完全禁用网络节流。这完全禁用了 MMCSS 的网络节流部分。我曾尝试简单地将值提高到70,但在我完全禁用它之前它并没有停止导致错误。

到目前为止,我还没有看到此更改对其他多媒体应用程序(也包括我自己的应用程序的视频捕获和音频输出部分)产生任何不利影响。如果情况发生变化,我会在这里报告。

于 2011-01-11T22:57:00.090 回答
1

众所周知,微软在 Windows Vista 内核中构建了一些奇怪的反功能,这些功能会预防性地降低 I/O 性能,以确保多媒体应用程序(Windows 媒体播放器、directX)获得 100% 的响应能力。我不知道这是否也意味着 UDP 丢包。阅读该方法的蹩脚理由:http: //blogs.technet.com/b/markrussinovich/archive/2007/08/27/1833290.aspx

那里的一条评论很好地总结了这一点:“在我看来,微软试图‘修复’一些没有被破坏的东西。”

于 2011-01-11T23:36:21.227 回答