10

我一直在阅读有关异构计算的内容并遇到了SPIR-V。在那里我发现了以下内容:

SPIR-V 是第一个用于本地表示并行计算和图形的开放标准、跨 API 中间语言。

这张图片中我可以看到所有高级语言,如 GLSL、HLSL、OpenCL C 等,都被编译成 SPIR-V,并以这种方式传递给正确的物理设备以执行。

我的问题是为什么我们需要将我们的着色器/内核代码编译为 SPIR-V,而不是将其直接编译为将由所选物理设备执行的机器指令?如果这个问题不正确,您能否解释一下我们为什么需要 SPIR-V?

4

1 回答 1

25

一般来说,您可以将编译器分为两部分:特定语言(或语言家族)的前端和后端,它与语言无关,可以为一个或多个特定架构生成机器代码(您可以进一步分解,但现在就足够了)。优化可以发生在两个部分;有些在这两个地方都更合适。例如,这是 clang 和 LLVM 之间的关系:clang 是 C 系列语言的前端,而 LLVM 是后端。

因为不同的 GPU 具有显着不同的机器代码(通常比 arm64 与 x86_64 大得多),后端编译器需要在 GPU 驱动程序中。但是没有理由让前端也在那里,即使这就是它在 OpenGL 中的工作方式。通过将两者分开,并使用 SPIR-V 作为他们用来交流的语言,我们得到:

  1. 一个解析和语法检查实现,而不是每个供应商一个。这意味着开发人员只能针对该语言的一个变体,而不是一堆特定于供应商的变体(由于实现不同的版本、错误、解释上的差异等)

  2. 支持多种语言。您可以使用 ESSL(OpenGL ES 的 GLSL 变体)、GLSL、HLSL 和 OpenCL-C 来编写 Vulkan 着色器,从而使开发人员更容易支持多个 API。都发出 SPIR-V,因此驱动程序不必支持这些语言中的每一种。理论上有人可以设计自己的语言,或者支持 MetalSL 等。

  3. 由于 SPIR-V 旨在由机器编写/机器读取而不是对人类友好,因此它是一种比 GLSL 更简单、更常规的语言。所以应该更容易让所有供应商高质量地实施它。(目前,实现远不如 GL 驱动程序成熟,所以我们还没有完全成熟。)

  4. 一些昂贵的优化可以离线完成,例如作为应用程序构建过程的一部分,而不是在运行时,当您试图在 16 或 33 毫秒内完成一帧时。

于 2018-04-02T21:46:36.827 回答