Oct 312007
 

早从Vista还叫Longhorn的那段时间,不少和我一样喜欢倒腾测试版操作系统的小白们就发现了Vista/Longhorn Server的声音跑得不是那么顺畅,容易出现暴音和跳音。当初我个人就写了一篇文章大致推断了一下问题并给出了个临时可用但不怎么好用的解决方案,见这篇:http://dawnh.net/windows/127/windows-vista-sound-issue/

现在Vista都Release这么久了,Longhorn也命名为Windows Server 2008等着明年上桌了,这个问题在几次版本更新后表面上似乎给解决了,实际上还一直存在,只是没那么明显而已。

上几个月,被人发现Vista在进行多媒体回放时网络子系统的性能会变得地下,Mark大牛仔细研究了下并发现在Vista里有个ugly hack为了保证声音系统听起来流畅而抑制其它子系统的内核中断,见这篇(英文):

http://blogs.technet.com/markrussinovich/archive/2007/08/27/1833290.aspx

然后国内的Vista博客的某大牛翻译了这一篇,喜欢看中文文章的看这里:

http://blogs.itecn.net/blogs/winvista/archive/2007/08/28/Vista-Network.aspx

昨天,终于有来自官方的声音了,WindowsVistaBlog上出现了这样一篇文章:

http://windowsvistablog.com/blogs/windowsvista/archive/2007/10/29/an-overview-of-windows-sound-and-music-glitching-issues.aspx

终于将这个现象用一个单词定义–glitch,同时简单解释了声音处理的流程:

  1. 从磁盘读取一块音乐文件
  2. 解码文件使其成为硬件可以理解并回放的格式
  3. 将解码后的数据复制入内核中的声音硬件的缓冲区
  4. 在适当的时间内将数据发送到硬件 
  5. 以10ms为间隔,重复1-4

在这个流程内,如果有其它原因导致内核被占用超过这个10ms,就会导致某块音频无法正常回放而出现glitch。至于为什么这个值是10ms,文章的解释为这恰好是人神经反应传导需要的时间,短了可以减少延迟,但人还反应不过来没意义,长了虽然可以减少内核处理声音这个过程的次数,但增加了延迟。比如如果1s重复一次,一次处理大约1S的音频流,那人从点播放到听到声音也至少需要1s,这不可接受。

然后即使为什么会出现这个glitch现象。总结了n种原因,但其实都一样,就是内核忙于处理别的高优先级的事情而无法脱身在10ms内去关照一下这个流程。这个别的高优先级的事情怎么会出现的原因就多了,比如CPU重载,GPU重载,网络设备重载,PCI忙不过来等等等等。

于是乎有人问了,为什么同样硬件,我以前XP/2003跑得好好的,到你Vista就不行?文章给出的观点是驱动程序设计问题导致的。

所以通篇讲了道理而没有实际解决问题。下面commenter就不愿意了。有的说是调度器bug掉了,有的说多媒体框架设计有问题。作者保留了一部分说是留待第二篇继续解释。

从文章看来,大体原因确实如同我前一篇文章那样猜想的是Windows声音子系统架构方面的变化,导致了对硬件厂商设计驱动时要求的变更。其实我第一篇文章中引用的Larry工程师的那篇介绍文章已经明明白白地把架构方面的变更解释得很清楚了,这里再发一下文章链接:

http://blogs.msdn.com/larryosterman/archive/2006/03/07/545451.aspx

解释中有一个新声音子系统的框图最为直观,这里直接抓过来看看

首先是XP的:

xpaudiostack

再是Vista/Longhorn的:

vistasharedaudiostack

可以很清楚地看到,在Vista中把原来存在的miniport以上的DirectSound和MME部分都变成由Windows Audio Service这个服务在用户态实现了。至于这样架构的优缺点论证去看原文。至少可以知道这里带来一个问题就是新的模型由于是用户态的系统服务,很容易在运行时因为其他内核高优先级IRQL导致context switch而丢掉那个10ms的处理过程,所以才有了glitch的问题。

回头再看看Mark的文章,正好能从另一方面印证这个问题:由于Audio太容易被抢占而导致glitch,那只能在别的子系统内暂作一些限制使其尽量不去抢占Audio。于是就出来了前面的那个故事。

最终这个问题变成了这样:反正MS的开发人员已经将新架构投入使用了,想回去已经是没门的事情了。那就只能敦促相应硬件厂商尽量按照新的 Windows Audio Session API (or WASAPI)来尽快改进其驱动来避免影响了,但是在过渡期间,偷偷地放几个ugly hack来缓解这个问题。

所以在小白的体验历程里就有这样一段插曲:测试版的Windows/Longhorn声音glitch比较严重,而在Vista正式版build 5600却表面上看不出问题,再某些特殊情况下还是会出现,至于放音乐网络吞吐量下降可以看作灵异事件。而在继续下来的Windows Server 2008中,从build 5600起到6001的各个CTP不断改进并优化,问题虽然比Vista严重,但至少在改进而没有直接往其他子系统埋地雷。

期望接下来的Windows Server 2008以及Vista SP1能以更理想的方式来处理掉这个问题吧。

另外补一个PS:由于多核处理器的天生多硬件thread优势,那10ms基本上都能处理到,此问题几乎无法重现,所以认为是调度器问题似乎有点冤。

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>