1.2 为什么 6 核或 8 核 CPU 也救不了#这是本文最反直觉的一点,所以我想说清楚:
更多的 CPU 核心对 GameThread 瓶颈没有帮助。
一位社区成员分享了他在密集城区游玩时的 Process Lasso 截图——这个模式一眼就能认出来:
[图片:社区成员的 Process Lasso 截图——i7-11700F,鸣潮运行在城区。Client-Win64-Shipping.exe 显示创建了 319 个线程,但整体 CPU 使用率读数只有 31%,与此同时游戏报告的响应压力是 100%。角落里的 CPU 柱状图呈现严重偏斜的分布——一小簇核心在苦干,绝大多数接近空转。]
来源:https://www.reddit.com/r/WutheringWaves/comments/1p2pwg0/cpu_issue_apparently_the_new_area_is_full/
这台机器有充足的计算能力。但决定你会不会卡的那些工作——NPC 行为树、交互 Handler、AI Tick 协调、脚本逻辑——并不能自由地分摊到所有核心上。其中很大一部分必须先经过 GameThread 这个协调点,才能被分派给工作线程,而这个点上的同步开销正是把某个线程顶到 100% 的原因。线程有 319 个;可关键路径能并行多少,受引擎线程约束限制。
我自己的 CapFrameX 测试印证了 Process Lasso 截图显示的模式:在 i7-12700KF + RTX 5070 上的两次城区会话中,CPU 单线程峰值达到 97–100%,而整体 CPU 负载平均只有 40–46%。聚合数字看起来没问题,但每线程的情况完全是另一回事。
vkguide 的多线程文章描述的正是 UE4 的这个毛病:
“你经常会看到虚幻引擎游戏在超过 4 核之后很难继续扩展……一款大量使用蓝图和 AI 计算的 UE4 游戏,会让 Game Thread 在一个核心上忙得不可开交,而机器上其他核心闲置。”
来源:https://vkguide.dev/docs/extra-chapter/multithreading/
Epic 自己的开发者文档也这么说:
“从设计上,许多引擎 API 与玩法操作并非线程安全,因此必须在 GameThread 上执行……Game Thread——中心执行线程:每帧协调所有游戏逻辑。” “但多线程并不总是银弹。有些任务本质上是串行的,强行拆分可能只带来复杂度而没有性能收益。”
来源:https://dev.epicgames.com/community/learning/tutorials/BdmJ/unreal-engine-multithreading-techniques
我在同一台硬件上采集了两次基准会话——i7-12700KF + RTX 5070,设置完全一致:1080p、画质设置、光追、DLAA、关闭帧生成。两座不同的城市,同一个问题:CPU 是不是天花板?
瑝珑(v1.0 城市):
平均帧率:40.2 · CPU 最大线程:97% · GPU 平均占用:54%
CapFrameX 帧时间——瑝珑 v1.0 城区巡游 瑝珑城区巡游期间的帧时间分布。注意持续的尖峰模式——以及约 t=85s 处 245ms 的离群值,那是我以最高速飞出城市边界时故意触发的(模式 B)。
星炬学院(v3.0 城市):
平均帧率:38.5 · CPU 最大线程:100% · GPU 平均占用:58%
CapFrameX 帧时间——星炬学院巡游 星炬学院巡游期间的帧时间分布。175ms 的离群尖峰(自然发生,非人为触发)出现时与 GPU 负载毫无相关性——与 V8 GC 的 stop-the-world 暂停相符。
两座城市。两次会话。答案都一样:CPU 最大线程饱和,GPU 大量闲置。两次会话互相印证——这不是某个区域或某个补丁的偶然产物。RTX 5070 平均只跑到 54–58%,而 CPU 最大线程顶在 97–100%,这是最清晰的信号。GPU 在等。而这只是待在城里——不是战斗,也不是压力测试。
移动端线程统计——直接确认:
社区成员 @xLOCKnLOADx(第 5 节引用的那篇 Reddit 移动端性能帖的作者)提供了移动端运行鸣潮的每线程负载数据。线程分布把答案直接摆出来了:
线程平均峰值GameThread74.9%93.9%RenderThread65.1%83.8%RHIThread52.1%69.5%TaskGraphHP 313.3%17.4%TaskGraphHP 48.5%12.5%TaskGraphHP 56.6%10.3%V8 DefaultWorker ×23.3% / 3.2%16.1% / 23.1%其余所有线程各自 <5%—GameThread 与 RenderThread 是绝对主力。TaskGraph 工作线程在工作,但都停在 13% 及以下。V8 DefaultWorker 的出现,则是 V8/Puerts 与主游戏线程同时活跃的直接运行时证据。
架构对比——鸣潮 vs. 明日方舟:终末地:
在同一台设备上剖析,终末地(AKE)的线程分布呈现出根本不同的形态:
线程平均UnityMain70.0%Job.Worker 120.3%Job.Worker 220.0%Job.Worker 314.8%Job.Worker 011.0%主线程负载相近(约 70%),但终末地的 Job Worker 是真正在干实事的——每个都有 20% 以上。这是 Unity 的 Job System 在有效地把模拟工作摊到多核上。相比之下,鸣潮的 TaskGraph 工作线程停在 7% 及以下。
还有一个很重要的行为差异值得指出:鸣潮的工作线程呈现锯齿状/突发式模式,而不是持续负载。它们短促地被激活、快速完成任务,然后停在那里等主线程派发更多工作或解决同步点。这不是缺乏并行能力——而是协调瓶颈:系统本可以用更多核心,但工作喂过来的方式不支持持续并行执行。这个说法比“更多核心没用”更精确——准确的说法是,额外的核心无法加速那些仍然串行在协调点上的工作。
鸣潮线程统计——GameThread 与 RenderThread 占据主导 移动端鸣潮的每线程负载。GameThread 与 RenderThread 承担了绝大部分工作。TaskGraph 工作线程活跃但贡献很小。V8 DefaultWorker 实例证实 Puerts/V8 运行时处于活动状态。来源:@xLOCKnLOADx
架构对比——鸣潮 vs. 明日方舟:终末地:
鸣潮线程分布
鸣潮——GameThread 74.9%,TaskGraph 工作线程 ≤13%。来源:@xLOCKnLOADx
终末地线程分布
明日方舟:终末地——Job Worker 各自 20% 以上,工作分摊到多核。来源:@xLOCKnLOADx
@xLOCKnLOADx 把实际含义总结得很直接:“基本上全是主线程,他提到的那些线程跟终末地这种游戏比起来其实干不了多少活。一颗 8 Elite 配上一颗猛的主核都卡成这样,低端硬件会怎么挣扎你可以自己想象。”
@argon1ut 的测试用例——分辨率与设置的受控扫描(Ryzen 9 7900X + RTX 5070 Ti)
在同一套硬件上测了三组配置,用来在分辨率/设置的光谱上分离瓶颈行为。图片:argon1ut_4k_rt_night.png、argon1ut_4k_rt_day.png、argon1ut_768p_low_fg4x.png。
argon1ut 4K 光追 夜间
配置 A——4K DLAA,光追最高,关闭帧生成,夜间
FPS 35 · 1% Low 31 · GPU 99% · CPU 12%
可见 150.2ms 的延迟尖峰
argon1ut 4K 光追 白天
配置 B——相同设置,白天
FPS 40 · 1% Low 15 · GPU 99% · CPU 17%
可见 127ms 的延迟尖峰
配置 C——1024×768 窗口化,全部最低(把人群密度与视距拉到最高来给 CPU 上压力),DLSS 超级性能,帧生成 4×,关闭光追: FPS 412 · 1% Low 200 · GPU 37% · CPU 17% · 延迟 26.7ms
argon1ut 768p 低画质 帧生成 4×——GPU 被刻意压低负载
配置FPS1% LowGPU%CPU%瓶颈A——4K 光追最高,夜间353199%12%GPUB——4K 光追最高,白天401599%17%GPU + 模式 B 尖峰C——768p 低画质,帧生成 4×41220037%17%都不是——星炬学院入口区域,压力未起这组受控数据说明了什么:
配置 A vs B——设置完全一致,只是夜间与白天。夜间帧率更低(35 vs 40),但 1% Low 更好(31 vs 15)。这个 1% Low 差异值得注意,但没有这两次会话的详细帧时间图,成因是模糊的——它可能反映模式 B 的复合尖峰、不同场景复杂度下 GPU 帧时间的波动,或者两者兼有。两次会话中 GPU 都是 99%,说明在 4K 光追下 GPU 是主要瓶颈。
配置 C——录制于星炬学院内部,但位于低密度出生区,尚未进入高 NPC 密度区域。在 768p 且 GPU 被刻意压低负载时,GPU 与 GameThread 同时都有裕量——帧率 412,1% Low 干净地达到 200。这不代表星炬学院的峰值压力表现。
配置 A/B 与配置 C 合起来看——同一颗 CPU,帧预算却天差地别。几组配置的总 CPU 利用率都在 17% 左右,说明在 A/B 中 CPU 并不是限制资源——帧时间主要被 GPU/光追开销占据。CPU 可能仍然在协调路径上,但在那些 4K 光追场景里,它不再是可见的首要限制因素。
来源:@argon1ut(独立技术分析者)
作者本人的 7800X3D 数据 + @argon1ut 的 7900X 对照——L3 缓存、稳态稳定性与离群行为
CapFrameX 会话录制于星炬学院区域,设置与 12700KF 基线会话大体相同。硬件:Ryzen 7 7800X3D(96MB L3 缓存)+ RTX 5070,1080p,最高画质,光追,DLAA,无帧生成。
7800X3D CapFrameX——星炬学院帧时间
额外的对照数据由 @argon1ut 提供:Ryzen 9 7900X + RTX 5070 Ti,1080p,最高画质,DLAA,无帧生成,不使用 NVIDIA Filters。这不是一次严格的 CPU 隔离测试——GPU、驱动/运行时状态、着色器缓存、路线、流送状态、叠加层/滤镜栈都不同——但作为同一类星炬学院压力场景的第二个高端 Zen 4 参考点,它很有价值。
7900X CapFrameX——星炬学院帧时间,来源:@argon1ut
指标12700KF 基线7800X3D + RTX 50707900X + RTX 5070 Ti(@argon1ut)解读平均帧率38.567.367.9X3D 与 7900X 都大幅超越 12700KF 基线1% Low 平均14.819.235.7这次采集里 7900X 的尾部表现更健康0.1% Low 平均9.95.323.47800X3D 这一轮被异常的灾难性离群值拖得很惨卡顿累计—2.66s(2%)0.28s(0.2%)@argon1ut 的那一轮避开了 300–470ms 的尖峰簇最严重的可见尖峰175ms约 450ms约 70ms 级别的可见尖峰尾部行为取决于不止缓存大小一个因素稳态下的 X3D 信号: 7800X3D 的采集在灾难性尖峰簇出现前后,都有着非常干净的常态帧时间主体。这正是 X3D 看起来最起作用的部分:对缓存敏感的密集巡游、GameThread 对象遍历、指针追逐、Actor/系统协调,以及流送管理开销。在这种稳态负载下,96MB 的 L3 缓存降低了 UE4 对象零散访问的代价,让模式 A 明显更干净。
7900X 的尾部行为: @argon1ut 的 7900X + 5070 Ti 采集尾部指标健康得多:1% 与 0.1% Low 更高,卡顿总时长短,也没有 300–470ms 的灾难性尖峰簇。他还表示整轮体验都很顺滑。这是一个重要补充:现代非 X3D 的 CPU,只要单线程性能强、频率高、核心多、缓存也还算大,依然可以带来流畅且好玩的鸣潮体验。X3D 并不是让游戏在 PC 上体验变好的唯一路径。
为什么不该过度解读那个 450ms 尖峰: 7800X3D 的最坏尖峰并不是一份干净的 CPU 证据。它可疑的地方在于:那一轮开了 NVIDIA Filters,而 @argon1ut 没开。NVIDIA Filters/Freestyle 会挂进渲染/后处理/驱动路径,可能引入罕见的运行时顿帧,却未必降低平均帧率。流送状态、边界行为、着色器/材质预热、V8/GC 压力、驱动/运行时差异,以及叠加层/滤镜行为,都可能贡献最坏的离群值。在移除 NVIDIA Filters 重测 7800X3D 之前,那个 300–470ms 的尖峰簇应当被视为外部变量或复合事件变量,而不是 X3D 的常态表现。
更健康的那一轮里模式 B 依然存在: @argon1ut 的曲线上仍然有可见的 70ms 以上尖峰,而基线帧时间只有约 15–20ms。这些尖峰未必主观上能感知到,但它们说明类似模式 B 的波动即使在一轮健康的高端非 X3D 测试里也不会消失。差别在严重程度:他的采集呈现出可管理的尾部,而开了滤镜的 7800X3D 那一轮呈现出可疑的灾难性放大。
更有力的结论: X3D 很可能是目前能买到的、对鸣潮稳态密集巡游负载——也就是模式 A——最有效的硬件缓解手段,因为鸣潮在星炬学院这类区域表现出很强的缓存敏感性。但最严重的离群事件牵涉到缓存局部性之外的更多系统。X3D 并不会让鸣潮对复合顿帧免疫;它只是让常态城内巡游的主体干净得多。
问:那么鸣潮需要的是更多 CPU 核心,还是更高的频率?
—— 勘误致谢:@eggsee(鸣潮移动端配置作者)提供了客户端日志证据,确认了鸣潮的 TaskGraph 线程组,从而使 1.1 节中的线程模型更准确。原文“只有一条 GameThread 车道”的表述属于过度简化。
密集城区的另一个贡献因素——mip 流送竞争:
社区成员 @eggsee 还指出了星炬学院这类区域卡顿的第二个机制:纹理 mip 流送竞争。即便是被遮挡的几何体——墙后、视野之外——依然会被流送进来,与可见内容争夺 mip 流送带宽。这会堵塞 mip 流送管线,并迫使 CPU 把 GameThread 预算花在管理那些当帧根本不会被看到的几何体的流送请求上。
在移动端,这一点还会与 GameThread 协调开销叠加,同时抬高 GPU 帧时间——这也是移动端追踪里 CPU 与 GPU 利用率有时不符合预期模式的原因。
一个实际推论:在新区域里的卡顿,常常会在待一段时间后自行好转,因为着色器编译完成、流送系统稳定下来了。这与“流送预热效应”相符,而不是纯粹的静态 GameThread 天花板——天花板是真的,但它的严重程度会随流送状态变化。
答案比二者都更微妙。原始频率与 IPC(每时钟指令数)确实重要,但对鸣潮来说,最有价值的 CPU 升级往往是更大的 L3 缓存——原因直接来自 1.3 节描述的架构问题。
简而言之:GameThread 的工作涉及不断访问散落在 RAM 各处的数据。更大的 L3 缓存让更多这类数据留在 CPU 附近,减少每次访问的停顿时间。这就是为什么 AMD 的 X3D 处理器——把额外 L3 缓存堆叠在芯片上——往往能给出明显更顺滑的鸣潮体验,即使它们的纸面平均帧率并不更高。一颗 Ryzen 5700X3D 的平均帧率可能低于 i7-12700KF,但城内区域的 1% Low 与帧一致性大概率会明显更好。
但要说清楚:X3D 是当前最好的硬件缓解手段,不是解药。 它降低卡顿的严重程度,却无法消除卡顿——因为根因是架构性的,不是靠堆硬件就能完全补上的缓存容量问题。GameThread 天花板、V8 GC 暂停、OOP 指针追逐,这些都还在。更大的缓存让它们痛得轻一些,而不是消失。
实用建议:如果你玩鸣潮会卡,而 GPU 利用率低于 80%——最该升级的是大 L3 缓存的 CPU,而不是新显卡。并且据此校准你的期待。