程序员折腾 Windows 系统调校的血泪史:那些你以为没用、实际真有用的优化

摘要

作为一个写了七八年后端、偶尔打打 FPS 的程序员,我一直对所谓的"电脑优化"持怀疑态度。直到自己的高配台式机在三角洲行动里频繁跳 Ping、PR 渲染掉速,我才开始认真研究 Windows 底层调度。本文记录了我从踩坑到填坑的全过程,分享几个真正有效的优化思路和参考资源。


一、我为什么开始折腾系统调校

先说背景。我的主力机配置是 i7-13700K + RTX 4070Ti + 32GB DDR5,去年花了一万五攒的。平时跑编译、跑 Docker、剪视频都算流畅,但有两个场景一直让我很头疼:

  1. 打三角洲行动 64 人模式,Ping 值显示 38ms 没问题,但每局必有十几次突然跳到 100ms+,而且毫无规律。
  2. PR 渲染长视频到一半的时候会突然掉速——前 10 分钟能跑满 GPU 编码器,后面就开始波动,一上一下像心电图。

我最初以为是硬件问题:换过网线、升级过路由器、重装过显卡驱动、甚至给 CPU 换了硅脂。折腾了两个月,问题依旧。

直到一个做游戏开发的朋友说了一句点醒我的话:“你的硬件没问题,是 Windows 在拖你后腿。”


二、最先被揪出来的问题:后台服务

程序员都知道 Linux 可以用 htop 看进程、用 systemctl 管服务。但 Windows 这边,大多数人连「服务」这个入口都很少点开。

我装了一个叫 Sysinternals Process Explorer 的工具(微软官方的,放心用),发现在"空闲"状态下,我的 Windows 11 有 137 个后台进程 在运行。其中:

  • SysMain(原 Superfetch):在后台疯狂预加载文件到内存
  • WSearch(Windows Search Indexer):持续扫描磁盘建立索引
  • DiagTrack(Connected User Experiences and Telemetry):上传诊断数据
  • TrustedInstaller:时不时冒出来检查更新

这些服务单独看 CPU 占用都不高(0.5%-2%),但问题在于——它们的 I/O 操作和 CPU 时间片请求是随机的。 当它们恰好和游戏/渲染进程同时请求 CPU 时间,就会产生微卡顿。

我写了个简单的 PowerShell 脚本,在游戏启动时自动停掉一批非必要服务:

# 游戏前执行:停用非必要后台服务
$services = @(
    "SysMain", "WSearch", "DiagTrack", "XboxNetApiSvc",
    "MapsBroker", "lfsvc", "BITS", "EdgeUpdate"
)

foreach ($svc in $services) {
    Stop-Service $svc -Force
    Set-Service $svc -StartupType Manual
}

Write-Host "游戏模式已就绪,后台服务已暂停"

实测效果:PR 渲染的"心电图波动"消失了。因为 SysMain 不再在渲染过程中突然跑去预加载别的东西。但游戏跳 Ping 的问题只改善了一半——这说明还有其他原因。


三、第二个发现:网卡在偷懒

我用 Wireshark 抓包分析游戏流量时发现一个现象:UDP 包的发送间隔不是均匀的,而是偶尔会出现一个 40-80ms 的"空窗期"。

这不符合游戏引擎的发送逻辑(通常是固定 tick 发送)。排查了一圈,最终定位到两个设置:

3.1 网卡节能策略

大多数 Intel/Realtek 网卡驱动默认启用了「节能以太网」(Energy Efficient Ethernet, EEE)和「中断调节」(Interrupt Moderation)。

中断调节的意思是:网卡收到数据包后,不是立刻通知 CPU 处理,而是攒到一定数量或达到一定时间再批量通知。这在下载大文件时可以提高吞吐量,但对实时游戏来说是灾难——每个包都在网卡缓冲区里多等了 20-50ms。

网卡高级设置里可以关闭这些选项:

  • Interrupt Moderation → Disabled
  • Energy Efficient Ethernet → Off
  • Green Ethernet → Off
  • Receive Side Scaling → Enabled(保留开启)

3.2 DSCP QoS 标记

更深一层的优化是给游戏 UDP 包打上 QoS 优先级标记。Windows 原生支持 DSCP(Differentiated Services Code Point),你可以通过组策略或 PowerShell 创建 QoS 策略:

New-NetQosPolicy -Name "GameUDP" `
    -AppPathNameMatchCondition "三角洲行动\game.exe" `
    -DSCPAction 46 `
    -IPProtocolMatchCondition UDP

DSCP 46 是 EF(Expedited Forwarding)标记,代表最高优先级的实时流量。虽然家用路由器不一定认这个标记,但网卡驱动和 Windows 网络栈自身会按照 QoS 策略调整发送队列的优先级排序。也就是说——数据包在离开你的电脑之前就有了"插队权"。

调完这些之后,三角洲行动的跳 Ping 从每局十几次降到了两三次。剩下那两三次大概率是服务器端的波动,客户端已经无能为力了。


四、输入延迟:一个藏在注册表里的问题

作为程序员,我对"延迟"的理解曾经只停留在网络层面。直到用 NVIDIA FrameView 实测了瓦洛兰特的端到端延迟——原来从鼠标点击到画面响应,中间隔了将近 22ms。

22ms 在 240Hz 显示器上相当于 5 帧的延迟。也就是说,你看到敌人出现在屏幕上的时候,实际上已经是 5 帧之前的画面了。

我花了一整个周末研究输入延迟链路,总结出三个关键优化点:

4.1 系统计时器精度

Windows 默认的全局计时器分辨率是 15.6ms。这个值决定了内核处理输入事件的最小时间粒度。

// 查询当前计时器精度
NtQueryTimerResolution(&minRes, &maxRes, &curRes);
// curRes = 156250 (即 15.625ms)

大部分游戏引擎会在启动时调用 timeBeginPeriod(1) 把精度提升到 1ms。但不是所有游戏都会这么做——特别是一些老游戏和独立游戏。而且,如果有别的程序调了更高精度,游戏启动后又被覆盖了,精度就会降回默认值。

解决方案是系统级的精度锁定,而不是依赖每个应用自己去设置。

4.2 USB 与 PCIe 休眠

Windows 的电源管理会在设备空闲时让 USB 控制器和 PCIe 链路进入低功耗状态。当你在游戏中突然移动鼠标时,USB 控制器从休眠唤醒需要 10-50ms——这就是"甩枪不跟手"的原因之一。

# 关闭 USB 选择性暂停
powercfg /setacvalueindex scheme_current 2a737441-... 48e6b7a6-... 0

# 关闭 PCIe ASPM(主动状态电源管理)
powercfg /setacvalueindex scheme_current SUB_PCIEXPRESS ASPM 0

4.3 MPO 叠加层

NVIDIA 的 MPO(Multi-Plane Overlay)允许多个表面独立渲染后合成。这个设计在理论上是好的——可以减少一次 GPU 拷贝。但在实际中,它可能引入额外的缓冲区等待,特别是当你开了游戏内覆盖(Overlay)、录屏或 Discord 叠加层的时候。

禁用 MPO 的注册表修改:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Dwm
OverlayTestMode = 5

这三个设置调完之后,FrameView 的端到端延迟从 22ms 降到了 16ms——少了约 6ms。说实话视觉上感觉不到 6ms,但手感上的"跟手度"提升是实实在在的,尤其是在快速拉枪和急停的瞬间。


五、我目前在用的方案

手动调校的缺点是:每次系统更新、驱动更新甚至安装了新软件之后,有些设置会被重置。我试过用脚本自动检测和恢复,但维护成本太高——Windows 更新一次就要改一次脚本。

后来我开始用一个叫 Quwix Beta 的调校平台。坦白说最开始是被它的 UI 吸引的——跟我日常用的 IDE 和终端配色很搭。用了一段时间之后发现真正方便的是「方案切换」:

  • ECO 模式:上班写代码、开会用。CPU 功耗限制在 65W,风扇基本不转。
  • TURBO 模式:下班打游戏、周末剪片子用。解锁全部功耗墙,自动执行上面提到的所有优化。

切换只需要点一下,不用每次手动跑脚本。对我这种懒人来说简直是救星。

他们的技术文档放在 quwix.top,有些底层原理的文章写得不错,我在第四节里关于计时器精度的内容就参考了他们的文档。对底层原理感兴趣的可以翻翻。

另外我现在同时用着它家另一个产品 FPS AI 私教——一个用大模型分析射击训练数据的工具。不过那是另一个话题了,有空再写。


六、几个我踩过的坑

6.1 不要同时用多个调校工具

常见的"优化套件"大多会修改同一批系统设置(注册表、电源策略、服务状态)。两个工具同时改同一个值,结果不可预期。我之前用过一个不知名的小工具,它把系统计时器精度锁到了 0.5ms,结果 CPU 功耗在待机状态下飙了 15W——锁得太激进,CPU 一直处于高频状态。

6.2 不要照搬别人的配置

每个人的硬件平台不一样,别人调得好不代表你也能照搬。比如 Intel 和 AMD 的睿频策略完全不同,Intel 需要关注 PL1/PL2 功耗墙,AMD 需要关注 PBO 曲线。网卡也是——Intel I225-V 和 Realtek RTL8125 的驱动设置界面都不一样。

理解原理比复制配置更重要。

6.3 系统还原点是你的好朋友

在改任何系统级配置之前,建一个还原点。Windows 自带的系统还原功能就够用了:

创建还原点 → 调校 → 跑两天 → 没问题 → 保留
                              → 有问题 → 还原重来

我有一次调网卡参数调太激进,结果整台机器连不上网。幸好有还原点,五分钟就恢复了。没有还原点的话就只能重装网卡驱动或者重置网络栈了。


七、总结

折腾了这几个月,最大的感悟是:

调校不是一个"做完就完了"的事情,而是一种持续管理。 就像你不会因为部署了一次服务器就再也不碰运维一样,系统调校也需要持续关注。

如果你也是「高配但觉得不够流畅」的那类人,建议从以下几个方向入手:

  1. 先用工具监控,找到瓶颈在哪(Process Explorer、Wireshark、FrameView)
  2. 从最明显的问题开始,一个一个解决,不要一口气全调
  3. 选择一个可靠的调校平台,减少手动维护成本
  4. 养成备份还原点的习惯,给自己留后路

希望我这几个月的折腾经历能让你少走一些弯路。


参考资源

以下是我在研究过程中觉得比较有价值的参考资料:

  • 《Windows Internals, Part 1》第七章(进程与线程调度)— 作者 Pavel Yosifovich
  • Microsoft Docs: System Timer Resolution
  • NVIDIA Developer: FrameView 使用指南
  • RFC 2474 — Differentiated Services Field (DS Field)
  • Quwix Beta 技术文档 — quwix.top(系统调校方案参考,部分底层原理的文章可免费阅读)
  • Sysinternals Process Explorer — Microsoft Docs
  • Wireshark 官方文档 — wireshark.org

本文纯属个人技术经验分享,文中所提工具和网站均基于个人使用经历。调校操作有风险,强烈建议在操作前创建系统还原点。


Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐