我一直在阅读有关异构计算的内容并遇到SPIR-V。在那里我发现了以下内容:
SPIR-V是第一个开放标准,跨API的中间语言,用于本地表示并行计算和图形。
从this image我可以看到所有高级语言,如GLSL,HLSL,OpenCL C等,都被编译成SPIR-V,并以这种方式传递给正确的物理设备执行
我的问题是为什么我们需要将着色器/内核代码编译到SPIR-V而不是将其直接编译成将由所选物理设备执行的机器指令?如果这个问题不正确,请解释为什么我们需要SPIR-V?
答案 0 :(得分:9)
通常,您可以将编译器分为两部分:特定语言(或语言系列)的前端和后端,后端与语言无关,可以生成一个或多个特定的机器代码架构(你可以进一步分解,但现在已经足够了)。两个部分都可以进行优化;有些更适合在任何一个地方。这是clang和LLVM之间的关系,例如:clang是C系列语言的前端,LLVM是后端。
由于不同的GPU具有明显不同的机器代码(通常与arm64与x86_64的差别更大),后端编译器需要位于GPU驱动程序中。但是没有理由让前端也在那里,即使它在OpenGL中的工作方式也是如此。通过将两者分开,并使用SPIR-V作为他们用来交流的语言,我们得到:
一个解析和语法检查实现,而不是每个供应商一个。这意味着开发人员只针对该语言的一种变体,而不是一堆特定于供应商的变体(由于实现了不同的版本,错误,解释上的差异等)。
支持多种语言。您可以使用ESSL(OpenGL ES的GLSL变体),GLSL,HLSL和OpenCL-C来编写Vulkan着色器,使开发人员更容易支持多个API。所有都发出SPIR-V,因此驱动程序不必支持这些语言。理论上,有人可以设计自己的语言,或支持MetalSL等。
由于SPIR-V意味着机器编写/机器读取而不是人性化,因此它比GLSL更简单,更常规。因此,让所有供应商以高质量实施它应该更容易。 (目前,实施比GL驱动程序要成熟得多,所以我们还没有完全实现。)
可以离线完成一些昂贵的优化,例如作为应用程序构建过程的一部分,而不是在运行时尝试在16或33毫秒内完成一个框架。