我在 Windows 10 中遇到了音频失真问题,但不同应用程序的严重程度有所不同。Foobar2000 在大多数曲目上失真非常严重,伴有嗡嗡声和跳跃。Windows Media Player 播放时也会失真,但似乎需要更长时间才能变糟。另一方面,Groove Music 听起来大部分都很好(可能有一些非常轻微的跳跃)。我在 KVM 下运行 Windows 10 并带有 pci 直通,但到目前为止,我没有发现任何理由认为 KVM/直通是问题所在。我使用的是 Ryzen Threadripper 1950x,为 Windows 分配了 32GB RAM。
到目前为止,我的故障排除尝试表明:
- 由于我之前遇到过一些问题,我认为这可能与通过网络播放音频有关。但是,我在本地 HD 上播放和在 NAS 上播放时遇到的问题是一样的。
- 其他机器播放 NAS 没有问题。
- 音频问题发生在 HDMI 输出和 USB-DAC 输出上。
- 它与资源管理器中显著显示的系统中断相关。
- 同样的硬件在Linux下也运行正常。
- 在过去的一年里,同样的硬件在同样的设置在 Windows 10 下运行正常。
- 我正在使用 PCI 直通让 Windows 访问我的 USB 和视频卡,尽管我已将 USB 卡交给了另一台 VM,因为我怀疑它会导致问题。
- 我已尝试关闭控制面板中的所有音频增强功能。
- 我尝试卸载高清音频驱动程序并重新安装。
- 我尝试了最新版本的 AMD 驱动程序,它是稳定版本的补充。
- 我为我的高清音频设备打开了 MSI 中断,但没有成功。我检查过的其他所有可能相关的设备都已打开 MSI 中断。
- 根据 DCP 延迟检查器,禁用我的网络驱动程序 Intel 92574L v12.17.10.8 似乎可以稍微减少 DPC 延迟,但并不能解决音频问题。
- 我切换到 netKVM virtio 驱动程序,这有一定帮助,但 Foobar2000 中的声音仍然很糟糕。
- Windows Performance Analyzer 显示, 中的某些变体占了 DPC/ISR 的大部分份额。我第一次尝试时,
ntoskml.exe
位于顶部。 其下的顶级子进程是ntdll.dll!<symbols disabled>
, 其下的是atikmdag.sys
。 Foobar.exe 和 ntoskml.exe 也很突出。 - 我尝试切换到不同的显卡(NVIDA 而不是 AMD),但问题是一样的,只是现在 NVIDIA 驱动程序在 DPC/ISR 中很突出。
以下是使用 Windows 性能分析器截取的屏幕截图,其中两个不同的 GPU 提供 HDMI 音频输出。在这两种情况下,计算机在第一部分处于空闲状态,我在中间播放了糟糕的 Foobar2000 音频,然后在最后让它空闲了一段时间。查看 DPC 延迟显示整个过程中延迟都很高,但在播放音频时延迟大幅增加。
我真的不知道接下来该怎么做。我的印象是符号可以帮助我获得更多细节,但我不知道该获取哪些符号,也不知道在哪里/如何使用它们。
答案1
嗯,看来 NUMA 节点固定是将延迟恢复到可接受水平的关键。我不知道为什么我以前不需要这样做,但现在却需要了,但看起来确实如此。今天还有一个 libvirt 更新,所以也许这起了作用,但我很确定我在更新和正确配置 NUMA 之间至少经历过一次失真。
核心的编号方式一开始让我很困惑,但是现在我已将所有内容固定到一个节点,LatencyMon 基本处于绿色状态,而且我在听音乐的几个小时内没有遇到任何音频中断。
我的域 XML 现在看起来像这样(请注意,我固定了 8 个逻辑核心,但有 4 个物理核心)。
<domain type='kvm' id='11'>
<name>WINVM</name>
<uuid>8602aa7a-df8a-4bc1-b609-7a26e98aad05</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://microsoft.com/win/10"/>
</libosinfo:libosinfo>
</metadata>
<memory unit='KiB'>33554432</memory>
<currentMemory unit='KiB'>33554432</currentMemory>
<memoryBacking>
<hugepages>
<page size='1048576' unit='KiB'/>
</hugepages>
</memoryBacking>
<vcpu placement='static' cpuset='4-7,20-23'>8</vcpu>
<cputune>
<vcpupin vcpu='0' cpuset='4'/>
<vcpupin vcpu='1' cpuset='20'/>
<vcpupin vcpu='2' cpuset='5'/>
<vcpupin vcpu='3' cpuset='21'/>
<vcpupin vcpu='4' cpuset='6'/>
<vcpupin vcpu='5' cpuset='22'/>
<vcpupin vcpu='6' cpuset='7'/>
<vcpupin vcpu='7' cpuset='23'/>
<emulatorpin cpuset='4-7,20-23'/>
</cputune>
<numatune>
<memory mode='strict' nodeset='0'/>
</numatune>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-q35-4.2'>hvm</type>
<loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
<nvram>/var/lib/libvirt/qemu/nvram/WINVM_VARS.fd</nvram>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<hyperv>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
<vpindex state='on'/>
<synic state='on'/>
<stimer state='on'/>
<vendor_id state='on' value='0123456789ab'/>
<frequencies state='on'/>
</hyperv>
<kvm>
<hidden state='on'/>
</kvm>
</features>
<cpu mode='custom' match='exact' check='full'>
<model fallback='forbid'>EPYC-IBPB</model>
<vendor>AMD</vendor>
<feature policy='require' name='x2apic'/>
<feature policy='require' name='tsc-deadline'/>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='arch-capabilities'/>
<feature policy='require' name='cmp_legacy'/>
<feature policy='require' name='perfctr_core'/>
<feature policy='require' name='clzero'/>
<feature policy='require' name='virt-ssbd'/>
<feature policy='require' name='rdctl-no'/>
<feature policy='require' name='skip-l1dfl-vmentry'/>
<feature policy='require' name='mds-no'/>
<feature policy='disable' name='monitor'/>
<feature policy='require' name='topoext'/>
</cpu>
<clock offset='localtime'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/home/boss/Downloads/Win10_2004_English_x64.iso' index='3'/>
<backingStore/>
<target dev='sda' bus='sata'/>
<readonly/>
<alias name='sata0-0-0'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/home/boss/Downloads/virtio-win-0.1.185.iso' index='2'/>
<backingStore/>
<target dev='sdb' bus='sata'/>
<readonly/>
<alias name='sata0-0-1'/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<disk type='block' device='disk'>
<driver name='qemu' type='raw' cache='none' io='native'/>
<source dev='/dev/nvme-tank/ntfs-zvol' index='1'/>
<backingStore/>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</disk>
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<alias name='usb'/>
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
</controller>
<controller type='sata' index='0'>
<alias name='ide'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pcie-root'>
<alias name='pcie.0'/>
</controller>
<controller type='pci' index='1' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='1' port='0x10'/>
<alias name='pci.1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='2' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='2' port='0x11'/>
<alias name='pci.2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
</controller>
<controller type='pci' index='3' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='3' port='0x12'/>
<alias name='pci.3'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
</controller>
<controller type='pci' index='4' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='4' port='0x13'/>
<alias name='pci.4'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
</controller>
<controller type='pci' index='5' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='5' port='0x14'/>
<alias name='pci.5'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
</controller>
<controller type='pci' index='6' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='6' port='0x15'/>
<alias name='pci.6'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
</controller>
<controller type='pci' index='7' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='7' port='0x16'/>
<alias name='pci.7'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
</controller>
<controller type='pci' index='8' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='8' port='0x8'/>
<alias name='pci.8'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
</controller>
<controller type='pci' index='9' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='9' port='0x9'/>
<alias name='pci.9'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='pci' index='10' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='10' port='0xa'/>
<alias name='pci.10'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='11' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='11' port='0xb'/>
<alias name='pci.11'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/>
</controller>
<controller type='pci' index='12' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='12' port='0xc'/>
<alias name='pci.12'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/>
</controller>
<controller type='pci' index='13' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='13' port='0xd'/>
<alias name='pci.13'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x5'/>
</controller>
<controller type='pci' index='14' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='14' port='0xe'/>
<alias name='pci.14'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x6'/>
</controller>
<controller type='pci' index='15' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='15' port='0xf'/>
<alias name='pci.15'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x7'/>
</controller>
<controller type='pci' index='16' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='16' port='0x17'/>
<alias name='pci.16'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
</controller>
<controller type='pci' index='17' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='17' port='0x18'/>
<alias name='pci.17'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:e6:4e:d1'/>
<source bridge='virbr0'/>
<target dev='vnet1'/>
<model type='virtio'/>
<driver name='qemu'/>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/2'/>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
<alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/2'>
<source path='/dev/pts/2'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<input type='mouse' bus='ps2'>
<alias name='input0'/>
</input>
<input type='keyboard' bus='ps2'>
<alias name='input1'/>
</input>
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x09' slot='0x00' function='0x0'/>
</source>
<alias name='hostdev0'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x09' slot='0x00' function='0x1'/>
</source>
<alias name='hostdev1'/>
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x0a' slot='0x00' function='0x0'/>
</source>
<alias name='hostdev2'/>
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
</hostdev>
<memballoon model='virtio'>
<alias name='balloon0'/>
<address type='pci' domain='0x0000' bus='0x11' slot='0x00' function='0x0'/>
</memballoon>
</devices>
<seclabel type='dynamic' model='apparmor' relabel='yes'>
<label>libvirt-8602aa7a-df8a-4bc1-b609-7a26e98aad05</label>
<imagelabel>libvirt-8602aa7a-df8a-4bc1-b609-7a26e98aad05</imagelabel>
</seclabel>
<seclabel type='dynamic' model='dac' relabel='yes'>
<label>+64055:+108</label>
<imagelabel>+64055:+108</imagelabel>
</seclabel>
</domain>