为什么我们需要 SPIR-V?

Why do we need SPIR-V?

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

SPIR-V is the first open standard, cross-API intermediate language for natively representing parallel compute and graphics..

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

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

一般来说,您可以将编译器分为两部分:front-end 用于特定语言(或语言家族),以及 back-end,即 language-agnostic 并且可以为一个或多个特定体系结构生成机器代码(您可以进一步分解它,但现在就足够了)。两个部分都可以进行优化;有些在任何一个地方都更合适。这是 clang 和 LLVM 之间的关系,例如:clang 是 front-end for C-family languages,LLVM 是后端。

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

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

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

  3. 因为SPIR-V意味着machine-written/machine-read而不是human-friendly,它是一种比GLSL更简单、更规则的语言。因此,让所有供应商使用 high-quality 实施它应该更容易。 (目前,实现远不如 GL 驱动程序成熟,因此我们还没有完全实现。)

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