PCEVA,PC绝对领域,探寻真正的电脑知识
  • 内容展现
  • 最新评论
Cyberpunk 2077锐龙补丁:提速10%
2020-12-14 14:23| 发布者: 绝对有料| 查看: 4656| 评论: 11|原作者: 绝对有料
摘要: 2020年都快过完了,想不到ZEN3架构的锐龙再次遇到负优化,而原因竟然和9年前的推土机架构有关。刚刚入手Cyberpunk 2077的AMD玩家一定要看!过去AMD处理器遭遇负优化都跟使用英特尔ICC编译器有关(英特尔显然没有 ... ...
2020年都快过完了,想不到ZEN3架构的锐龙再次遇到负优化,而原因竟然和9年前的推土机架构有关。刚刚入手Cyberpunk 2077的AMD玩家一定要看!


过去AMD处理器遭遇负优化都跟使用英特尔ICC编译器有关(英特尔显然没有义务给AMD做优化),但这次有所不同,AMD在Cyberpunk 2077中CPU使用率上不去、性能发挥不出来的原因跟GPUOpen SDK有关,程序会检查CPU的品牌和架构,并分配不同的线程数以充分利用CPU计算效能。

不用很丰富的编程经验,大家很容易看出上面这段代码的逻辑和其中的BUG。第一重IF-ELSE结构判断CPU的品牌,如果是非AMD品牌(英特尔)则直接返回逻辑核心数。第二重IF-ELSE是在AMD品牌下判断其是否属于推土机架构,如果是则使用全部逻辑核心,否则将只使用物理核心数量的线程。这个BUG太过明显,似乎是写反了。

锐龙并不属于老旧的推土机架构,按照上面的代码逻辑,6核心12线程的Ryzen 5 5600X属于AMD处理器,但不是推土机架构,所以只按物理核心数量分配线程,也就是游戏只使用6个线程。这样一来,Ryzen 5 5600X的CPU使用率就上不去,性能得不到充分发挥。


好在民间大神已经发现问题并提供了一个手动补丁,即通过十六进制编辑器打开Cyberpunk2077.exe可执行文件,搜索“75 30 33 C9 B8 01 00 00 00 0F A2 8B C8 C1 F9 08”,并将其替换成“EB 30 33 C9 B8 01 00 00 00 0F A2 8B C8 C1 F9 08”,最后保存文件。

这将绕过带有BUG的逻辑检查,使AMD锐龙得以利用全部线程运行Cyberpunk2077:


不过Tom’s Hardware的测试指出,这个民间补丁似乎只对8核心及以下的AMD锐龙有较好的提速效果。对于Ryzen 9 5950X,打完补丁后性能反而会有所下降,这可能跟跨CCD后延迟增加有关,如果猜想不错的话,Ryzen 9 5900X也会有类似问题。

有了这个补丁,Ryzen 5 5600X游戏离游戏神U又近一步,打过补丁后它的性能反超英特尔Core i9-10900K,性价比凸显。
收藏 邀请
1
本文版权归 PCEVA,PC绝对领域,探寻真正的电脑知识 原作者所有 转载请注明出处
发表评论

最新评论

引用 wmk19700212 2020-12-14 22:57
凸显了3500X的优秀?!
引用 McLaren 2020-12-15 10:21
如果反过来看,发行商居然还能想着古老的推土机架构并专门做出判断,别的发行商可能根本不会想到这个问题。
引用 congrongdeyu 2020-12-15 10:39
ryzen 1700 玩的的时候,没有出现类似的bug,所有逻辑核心都在工作。
引用 alex310110 2020-12-15 15:32
McLaren 发表于 2020-12-15 10:21
如果反过来看,发行商居然还能想着古老的推土机架构并专门做出判断,别的发行商可能根本不会想到这个问题。 ...

开发商只是调用了一个开源库吧。

好多地方新闻都没看到改这个二进制代码的原因,总算在PCEVA看到了……
引用 eikeime 2020-12-15 16:17
alex310110 发表于 2020-12-15 15:32
开发商只是调用了一个开源库吧。

好多地方新闻都没看到改这个二进制代码的原因,总算在PCEVA看到了……

我倒是再几个网站看过这个问题的说明,但是每次引用的代码都是不一样的
引用 alex310110 2020-12-16 13:56
本帖最后由 alex310110 于 2020-12-16 13:57 编辑
eikeime 发表于 2020-12-15 16:17
我倒是再几个网站看过这个问题的说明,但是每次引用的代码都是不一样的。 ...

网上随便找了个x86-64二进制反汇编网站 https://defuse.ca/online-x86-assembler.htm#disassembly2,贴进去看了下(多贴了个83 e1 0f ),那个操作把
  1. 0:  75 30                   jne    0x32
  2. 2:  33 c9                   xor    ecx,ecx
  3. 4:  b8 01 00 00 00          mov    eax,0x1
  4. 9:  0f a2                   cpuid
  5. b:  8b c8                   mov    ecx,eax
  6. d:  c1 f9 08                sar    ecx,0x8
  7. 10: 83 e1 0f                and    ecx,0xf
复制代码


改成了

  1. 0:  eb 30                   jmp    0x32
  2. 2:  33 c9                   xor    ecx,ecx
  3. 4:  b8 01 00 00 00          mov    eax,0x1
  4. 9:  0f a2                   cpuid
  5. b:  8b c8                   mov    ecx,eax
  6. d:  c1 f9 08                sar    ecx,0x8
  7. 10: 83 e1 0f                and    ecx,0xf
复制代码


所以就第一条指令改掉了,相当于文中C/C++代码里的某个cpuid之前的if改成了强制goto(那大概率就是第75行的if了)。0x32大概是跳到当前指令地址+0x32之后的指令?那么就是相当于跳过了cpuid指令的部分,也跳过了上述汇编代码部分,估计就直接84行“return count;”了。jne是在“不等”的情况下跳转;如果“等于”的话,也就是说是strcmp确认是AMD处理器,所以jne指令不起作用,进入上述汇编代码的cpuid测试。

根据维基百科 https://en.wikipedia.org/wiki/CPUID#EAX=1:_Processor_Info_and_Feature_Bits,上述0x2到0x10行汇编也就是取维基百科链接表格中Family ID的部分。

综上我觉得还蛮可信的……这个二进制补丁结果就是,任何处理器一律用逻辑核心数量。至于为什么会有这个源代码这个写法,那么得接着去看git log了……

引用 eikeime 2020-12-16 14:03
alex310110 发表于 2020-12-16 13:56
网上随便找了个x86-64二进制反汇编网站 https://defuse.ca/online-x86-assembler.htm#disassembly2,贴进 ...

我不是怀疑可信性,我只是觉得 不同媒体 选择了不同版本的 gpu open 的源码 来解释 这个问题,而不是 一味的复制粘贴。
引用 alex310110 2020-12-16 15:00
eikeime 发表于 2020-12-16 14:03
我不是怀疑可信性,我只是觉得 不同媒体 选择了不同版本的 gpu open 的源码 来解释 这个问题,而不是 一 ...

有哪些版本差异吗?至少我看主楼里源码和二进制都还对得上的样子……
引用 alex310110 2020-12-16 15:19
alex310110 发表于 2020-12-16 13:56
网上随便找了个x86-64二进制反汇编网站 https://defuse.ca/online-x86-assembler.htm#disassembly2,贴进 ...

在GitHub上找了一下代码和对应修改成现在这样的commit:

https://github.com/GPUOpen-Libra ... dCount-Win7.cpp#L69
https://github.com/GPUOpen-Libra ... 5e5192b4c14215151dc

看样子原来代码确实有问题,只有推土机用逻辑核心数量,别的CPU全用物理核心数量。改完之后,Intel和推土机都用逻辑核心数量,剩余AMD产品全用物理核心数量,然后就把Zen坑了……

引用 NOIP117 2020-12-19 18:45
然而对帧数并没什么提升

查看全部评论(11)

热门评论
    返回顶部