为什么我们需要SPIR-V?

Dim*_*tov 2 opengl opencl vulkan spir-v

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

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

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

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

Jes*_*all 10

通常,您可以将编译器分为两部分:特定语言(或语言系列)的前端和后端,后端与语言无关,可以为一个或多个特定体系结构生成机器代码(您可以进一步打破这一点,但现在已经足够了).两个部分都可以进行优化; 有些更适合在任何一个地方.这是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毫秒内完成帧时的运行时.

  • 前端将GLSL或HLSL等语言翻译成中间表示SPIR-V.后端读取SPIR-V并生成机器代码.在OpenGL中,驱动程序从GLSL转换为专有的内部中间表示,并从那里转换为机器代码.Vulkan没有内置前端,它只处理SPIR-V作为输入.[glslang](https://github.com/KhronosGroup/glslang)是Vulkan最常用的前端,用于将GLSL或HLSL转换为SPIR-V,但也有[clspv](https://github.com)/google/clspv)for OpenCL. (3认同)