Glsl 有没有办法在Vulkan SPIR-V中使用OpenCL C mad函数?
正如我们所知,至少有两种方法可以计算Glsl 有没有办法在Vulkan SPIR-V中使用OpenCL C mad函数?,glsl,opencl,vulkan,fma,Glsl,Opencl,Vulkan,Fma,正如我们所知,至少有两种方法可以计算a*b+c: ret:=a*b;ret:=ret+c ret:=fma(a,b,c) 但在OpenCLC中,还有第三个函数叫做“mad”,它以精度换取性能 在LunarG sdk中,默认SPIR-V编译器编译GLSL和HLSL着色语言,GLSL规范v4.60中未提及“mad”函数 如何在Vulkan中使用“mad”函数 这里有点误解 融合乘法加法并不意味着精度降低。这可能意味着,由于操作步骤之间保持的内部硬件精度差异,与应用乘法然后加法vs fma的数字略有不
a*b+c
:
ret:=a*b;ret:=ret+c代码>
ret:=fma(a,b,c)代码>
如何在Vulkan中使用“mad”函数 这里有点误解 融合乘法加法并不意味着精度降低。这可能意味着,由于操作步骤之间保持的内部硬件精度差异,与应用乘法然后加法vs fma的数字略有不同。因此,在某些API/语言中,自动FMA在默认情况下不启用,只有在编译器中使用快速数学或特定标志时才会启用。有些系统可能会导致精度降低,但这并不是它所暗示的 然而,在SPIR-V中,虽然似乎没有针对FMA的特定指令,但规范明确预测并允许它在SPIR-V->gpu汇编后编译。它甚至在语言中有一个
NoContraction
装饰
无合同
应用于算术指令以指示
操作不能与另一条指令组合形成一条指令
手术例如,如果应用于OpFMul,则该乘法不能
与加法结合,产生融合的乘加运算。
此外,不允许此类操作重新关联;例如。,
不能将add(a+add(b+c))转换为add(add(a+b)+c)
请注意,SPIR-V不是着色器的全部。它只是着色器的可移植中间表示形式,然后由供应商vulkan驱动程序进一步编译。没有机器直接运行SPIR-V。这些类型的优化由驱动程序执行,而不是由程序员执行。您通常可以假设这样的优化将在适当的条件下发生,这对于缺少显式FMA内置项的其他编程语言也是一样的 我正在Khronos group的GitHub上试验SPIRV-LLVM转换器,如果我在Vulkan中成功运行OpenCLC内核,我将添加我自己的答案;如果内核类型不兼容,我也会指出这一点。我已经在SPIR-V v1.4rev1规范中确认,既没有FMA也没有MAD。