PS3:被舔过的 Many-Core 曲奇

这篇文章的灵感来自于 I want a good parallel computer

理解为什么 PS3 失败至关重要。这里的视角是一位在 AAA 游戏中从事模拟和渲染的初级开发人员。我记得的没有我曾经知道的多,而我曾经知道的又比大多数人少!

OG PS3

然而,我能提供的是一位真正开发并发布了 PS3 平台游戏的开发者的事后诸葛亮视角。我希望 PS3 能够成功。更具体地说,我希望 Many-Core 能够成功。

PS3 让开发者们感到失望,因为它是一台过度异构的计算机; 并且底层异构计算难以组合。2

更像是 Multicore 而不是 Many

Many-Core 的主要特征,顾名思义,是其高核心数。Many-Core 仅仅是一种权衡,通过更显式(程序员)的控制来实现广泛的并行性。

CPU | GPU | Many ---|---|--- 少量复杂核心 | 宽 SIMD | 许多更简单的核心 低延迟,OOO,超标量 | 向量指令流水线,高延迟 | 类 RISC,标量 缓存和一致性协议 | 栅栏,刷新,不一致 | 消息传递,本地存储,DMA 显式粗粒度同步 | 隐式调度 | 显式细粒度同步

乍一看,PS3 的 SPE 似乎符合要求。它们_似乎_具有 Many-Core 的所有特征。问题是最重要的特征,即有很多核心,严重不足。

PS3 heterogeneous diagram

首先,作为(游戏)开发者,你无法获得完整的 8 个 SPE。在 8 个 SPE 中,一个由于芯片良率而被禁用,操作系统占用了一个半核心。虽然这随着更新而改变,但实际上只有 5-6 个 SPE 可用。相比之下,Xbox360 相当于 3 个 PPE(多 2 个)。因此,Cell 实际上最多比 Xbox360 多 3 个(难以使用) 核心。

计算能力薄弱的组件

Wiki 的说法是单个 SPE 具有 25 GFlops,PS3 GPU 具有 192 GFlops。即使你完全最大限度地利用你的 SPE,你仍然无法接近性能不足的 PS3 GPU 的能力。 相比之下,Xbox360 GPU 具有 240 GFlops。PS3 的 GPU 具有单独的顶点和像素着色器。相比之下,XBox360 共享计算资源,因此它可以在繁重的顶点着色与繁重的像素着色之间进行负载平衡。(这里的例子是角色骨骼动画 与 UI 渲染)。

PS3 heterogeneous diagram

作为一名游戏开发者,这些 Flops 数字反映了在这些相应平台上开发的经验。这在后期处理中尤其明显,因为顶点单元的需求非常低(大型四边形)。

由于 GPU 顶点单元的弱点,开发人员会使用 SPE 来进行骨骼动画。像素着色器单元没有常量。因此,在将这些程序发送到 GPU 之前,还必须在 SPE 上进行着色器修补。所有这些都需要 CPU、SPE 和 GPU 之间的同步,并与工作负载平衡相互作用。回想起来,我还假设着色器中的动态分支要么是不可能的,要么是代价过高的,这就是为什么每个人都进行过多的着色器排列。这意味着 10 兆字节的着色器。再次将此与支持波操作 3 的 XBOX360 进行对比,我甚至在过去使用过此功能。因为 PS3 的每个组件本身都很弱,所以必须一起使用它们才能与(不太)异构的平台竞争。

计算机不是超级的

虽然 Cell 可以更像一台超级计算机一样工作,但我看到它主要用作通用的 GPU 计算。我从未见过生产代码做过除了从 PPE 分派 N 个作业之外的任何事情。我从未见过直接的 SPE 间通信,即使我记得这种事情是可能的(邮箱)。这类似于 GPU 工作组间工作负载的稀有性和难度。

异构性无处不在。即使 PPE 也与 SPE 非常不同。SPE 只有向量寄存器;PPE 具有 fp、gp 和向量寄存器。这真的很糟糕吗?不 4,但它使一切变得更加异构,因此更加复杂。要从这些 SPE 单元中获得最大性能,意味着你很可能在进行异步 DMA 的同时也在进行计算工作。这些细微差别对于顶级程序员来说可能是一个有趣的挑战,但最终会成为游戏工作室开发的障碍。

锋利的边缘

PS3 总共有 512 Mb 内存,但 256 MB 专用于图形,并且只能从 CPU 以 REDACTED Mb/s 的速度访问。因此,这意味着除了 256 MB 纯粹用于图形之外,你还必须为写入和读取 GPU 的任何内容分配系统内存。这里的重点是不灵活性和异构性。

PS3 具有很酷的功能,但这些功能从来不是通用的,只能通过仔细关注细节,有时甚至是重大的引擎更改来利用。我记得使用深度边界进行屏幕空间阴影,并且可以将其用于一些其他类似的 GPU 技术(光照)。还有诱人的双 z 写入,如果你不实际使用像素着色器,这对于深度贴图来说是一次性的。我不记得所有的边缘,但它们很锋利,这意味着如果偏离它们,性能会急剧下降。下一节介绍所有边缘中最锋利的边缘。

本地内存的挑战

当然,每个人都知道的 SPE 的挑战是将内存访问限制在本地内存。你获得了 256Kb,但实际上,一旦你考虑到堆栈和程序,你可能只剩下 128Kb 了。这种计算模型比现代 GPU 计算的限制性更大,因为至少在那里你可以直接访问存储缓冲区。

大多数代码和算法都无法简单地移植到 SPE。 C++ 虚函数和方法无法直接工作。C++ 鼓励动态分配对象,但这些对象可以指向主内存中的任何位置。你需要将指针地址从 PPE 映射到 SPE,才能尝试在 SPE 上运行普通的 C++ 程序。此外,空值(地址 0x0)指向本地内存的开头,并且从中加载不会导致段错误。

因此,开发人员没有在 SPE 上运行通用代码,而是为引擎中繁重但可并行化的部分编写了手工制作的 SPE 友好的代码。凭借足够的人才和投资,你可以榨干 PS3 的全部计算能力。5 当然,作为一家第一方开发商,这可能更容易,因为你至少可以专注于这种异构硬件,并围绕可用的计算类型来设计你的引擎和游戏功能。这就是为什么 Naughty Dog 如此接近向我们展示控制台的全部潜力的原因。

[Uncharted 3: Mobygames image](https://darkcephas.github.io/ps3_failed/< https:/www.mobygames.com/game/53611/uncharted-3-drakes-deception/screenshots/ps3/531831/>) Uncharted 3 PS3 credit mobygames

本该如何

如果 PS3 按照最初的设计,它本应该是一台更加异构但更加不异构的机器。

最初的设计大约是 4 个具有高频率的 Cell 处理器。也许对这种设计进行改进会产生非常同质的高性能 Many-Core 架构。凭借超过 1 TFlop 的通用计算能力,它将成为一头野兽,但不是一头令人讨厌的野兽,而是一只光滑、均匀的老虎。

人们实际上必须将 PS3 视为 Many-Core 设计的 舔过的曲奇 6 。这种半生不熟、半心半意的尝试成为了 Many-Core 失败的代名词。我曾经认为 PS3 使 Many-Core 倒退了几十年,现在我想知道它是否只是永远扼杀了它。

Refs

1 Some of the titles I have worked on. 2 我不会提供证明或参考,但数学问题是空间没有被均匀覆盖。这种低级别的可组合性问题通常在编写汇编时会出现在指令选择中。 3 The XBox360 gpu had wave operations like ifany/ifall that are similar to modern control flow subgroup operations. 4 The fact that it was only vectors on the SPEs was present to the programmer due to loads/stores having to also be vector aligned 5 [PS3 SPE usage](https://darkcephas.github.io/ps3_failed/< https:/www.neogaf.com/threads/ps3-games-list-spe-usages.184843/>) : it is clear that some games had higher utilization than others. 6 I am not sure my usage fits Raymond's narrow specifications. classic.copetti.org Source for images and some technical specifications.