绝对有料 发表于 2020-12-14 14:23

Cyberpunk 2077锐龙补丁:提速10%

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,性价比凸显。

wmk19700212 发表于 2020-12-14 22:57

凸显了3500X的优秀?!http://www.pceva.com.cn//mobcent//app/data/phiz/default/30.png

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看到了……


我倒是再几个网站看过这个问题的说明,但是每次引用的代码都是不一样的{:7_358:}。

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 ),那个操作把
0:75 30                   jne    0x32
2:33 c9                   xor    ecx,ecx
4:b8 01 00 00 00          mov    eax,0x1
9:0f a2                   cpuid
b:8b c8                   mov    ecx,eax
d:c1 f9 08                sar    ecx,0x8
10: 83 e1 0f                and    ecx,0xf

改成了

0:eb 30                   jmp    0x32
2:33 c9                   xor    ecx,ecx
4:b8 01 00 00 00          mov    eax,0x1
9:0f a2                   cpuid
b:8b c8                   mov    ecx,eax
d:c1 f9 08                sar    ecx,0x8
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-LibrariesAndSDKs/cpu-core-counts/blob/49a6e7349dd3a73dfc4e85e5192b4c14215151dc/windows/ThreadCount-Win7.cpp#L69
https://github.com/GPUOpen-LibrariesAndSDKs/cpu-core-counts/commit/49a6e7349dd3a73dfc4e85e5192b4c14215151dc

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

NOIP117 发表于 2020-12-19 18:45

然而对帧数并没什么提升
页: [1]
查看完整版本: Cyberpunk 2077锐龙补丁:提速10%