主题 : 【分享】土星日版游戏 毁灭战士 DOOM 优化版更新V3,更爽快了
jackerlxf
级别: 模拟专家
UID: 322239
精华: 0
发帖: 64
威望: 0 星
金钱: 129 浮游币
贡献值: 3566 点
好评度: 167 点
人气: 0 点
在线时间: 124(时)
注册时间: 2023-12-05
最后登录: 2026-06-22
楼主  发表于: 2026-05-15 22:51

【分享】土星日版游戏 毁灭战士 DOOM 优化版更新V3,更爽快了

在v0.3中:
忘了之前提到,但是进行汇编技巧可以在SH2流水线的约束下优化代码:
尝试在分支上使用延迟插槽(一个跟随在分支指令之后的额外指令,处理器在分支指令之前执行,如果分支被取,则可以减少周期成本)。
尽量将内存访问指令放在4的倍数的内存地址上。这避免了与SH2为了获取指令对而自动进行的内存访问的冲突。内存访问指令包括访问SH2乘法器或除法器的指令。对于内存读取,无论数据来源是外部内存还是缓存,都是有效的。
尽量避免在刚执行完内存访问指令后立即使用被该内存访问指令加载的寄存器。
在乘法指令和读取乘法结果的指令之间至少插入一条指令。这可以减少乘法的周期成本。
那些规则复合在一起,使汇编代码呈现出多线程的样子,因为它会让你穿插执行不同任务的指令。这不是混淆,而是真的试图让SH2运行得更快!
使用 SH2 的 MAC(乘法和加法)指令重写矩阵乘法,这些指令比之前使用的乘法指令更高效。
尽可能在SH2分割单元上进行平行分割。
当不可能时,尽可能使用更快的32位/16位=16位除法(与SH2的除法单元非并行化的除法相比,大约需要20到30个周期)。由于它们使用SH2指令,甚至可以在除法单元上与另一个除法并行化!
尽可能使用更快的字乘法 SH2 指令(长字乘法需要 2 到 4 个周期,而 SH2 指令只需 1 到 3 个周期)。
尽可能避免或延迟右移操作,以获得性能和精度。这通常可以通过使用完整的SH2乘数器,64位,而不是限制其使用到32位来实现。
当需要移位时,尽可能使用逻辑(无符号)移位而不是算术(有符号)移位。在SH2上,逻辑移位比算术移位更快,因为有指令可以一次移多位,而算术移位指令只能逐位移位(PSX的Doom中有一些部分被Saturn的Doom继承,真的充满了算术移位!)。
通过尽可能将所需值保留在寄存器中,减少对堆(局部)变量的使用。这不仅通过消除有时冗余的内存访问来读取和更新这些堆变量来加速程序,而且,如果通过将一些变量完全从堆中逐出,减少堆分配,还能通过减少读取堆时使用的缓存行来提高SH2缓存效率。
通过将一些数组的元素大小调整为更小的单位来减少数组的大小:这也能提高SH2缓存的效率,并为其他内容释放工作内存空间。
去除分支,当没有它时可以更快地进行相同计算(通常涉及位操作)。
有些跳跃将仅在特殊情况下而非几乎总是进行。特别地,始终将此原则应用于某些错误处理的恢复,尽管在商业版本中被无效化,但仍然保留了所有必要的分支,并且有系统性的跳跃用于正常无错误的路径。
对 BSP 遍历进行高级优化重写,以避免一些无用的转换和除法,加快墙剪辑缓冲区的读取和更新,扩展剪辑缓冲区的使用,剪辑更多的墙,更重要的是剪辑平面,减少所需的软件渲染量。
在不降低性能的情况下尽可能提高BSP计算的精度,能够消除许多图形中的间隙,从而能够消除每边各2像素的平面跨度扩展。这些扩展继承自PSX版本,曾用于隐藏一些间隙,但它们通过增加需要渲染的跨度像素数量而降低了性能,并且它们也是视觉上的烦扰。虽然一些间隙仍然可见,但只有在与天空重叠时才会明显,这也是为什么游戏在不可见时会关闭天空(在 Saturn 上是 VDP2 层)。
将平滑渲染并行化重写,以减少处理跨度之间奴隶SH2的停机时间。不是在奴隶CPU上交替处理一个跨度,在主CPU上处理一个,新的并行化使用由主SH2构建的跨度渲染参数列表。列表处理可以由两个CPU以相反的方向执行,以减少对已处理参数的扫描,将其减少到一个。跨度参数有一个锁位,通过特殊的原子指令(TAS.B)测试和设置,以确保给定跨度只被渲染一次。主SH2在第一个跨度参数完成后,立即触发奴隶SH2处理列表。主SH2在完成每个后续跨度参数后也会进行检查,以确保从属设备仍在处理(以防它比主SH2更快地耗尽列表),并在必要时重新触发从属设备的处理。在这种情况下,从属SH2从它停止的地方恢复处理。当主SH2完成列表构建时,它从相反的一端开始处理该列表。
通过为子区域生成一个包含所有软件渲染跨度纹理的单一VDP1命令列表,进一步增强平面处理,该列表可以一次性传输到VDP1 VRAM,而不是像以前那样需要将四个单独的列表(每个CPU一个命令列表和一个跨度纹理列表)分别传输到VDP1 VRAM的固定位置。这不仅减少了传输开销,还减少了为这些列表分配的VRAM量,释放了10%的VRAM,以增加精灵纹理缓存的大小。这是利用VDP1能够通过跳转处理非连续命令的能力,跳过插入的跨度纹理。
平滑纹理列表的大小通过允许跨度纹理在前一个VDP1缩放精灵命令的最后8个字节开始,从而减少传输到VDP1的时间。事实上,这8个字节对VDP1处理命令没有用。这样做使这些纹理的起始地址在VRAM上对齐8但不对齐32。这违反了VDP1手册中VDP1约束条件,即纹理在VRAM中的起始地址应对齐32,但已知的VDP1问题只有在违反其他规则时才会出现,而Doom没有这样做。实际上,商业版本在处理墙柱纹理时已经违反了这一规则,它将纹理调整为8的倍数,而不是32的倍数,而修复补丁也保持了这一点。
重写墙壁处理函数,该函数存在上述列出的一些问题(从PSX版本继承的一系列算术移位、过度使用除法、由于代码复杂性和可能也因为编译器在调试模式下,导致堆变量的重复访问)。
移除了更多无必要的VDP1绘图结束等待,这些等待在某些情况下发生在没有后续绘图的墙或子段处理之间,当VDP1 VRAM中的精灵纹理缓存达到阈值时被重置。
对VDP1剪切区域和擦除多边形大小进行一般调整,以确保不超过可见范围并需要擦除。
移除了每个屏幕帧触发的3个中断之一,通过将从SMPC收集控制器输入的中断与垂直同步(vblank)合并来实现。这样在不增加输入延迟的情况下获得了一点性能提升。

jackerlxf
级别: 模拟专家
UID: 322239
精华: 0
发帖: 64
威望: 0 星
金钱: 129 浮游币
贡献值: 3566 点
好评度: 167 点
人气: 0 点
在线时间: 124(时)
注册时间: 2023-12-05
最后登录: 2026-06-22
沙发  发表于: 2026-05-15 22:54



哪位帮我发一下链接
jackerlxf
级别: 模拟专家
UID: 322239
精华: 0
发帖: 64
威望: 0 星
金钱: 129 浮游币
贡献值: 3566 点
好评度: 167 点
人气: 0 点
在线时间: 124(时)
注册时间: 2023-12-05
最后登录: 2026-06-22
板凳  发表于: 2026-06-10 17:38

回 2楼(ftg6900) 的帖子

谢谢,等级低,发不了链接