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)

  • 但在OpenCLC中,还有第三个函数叫做“mad”,它以精度换取性能

    在LunarG sdk中,默认SPIR-V编译器编译GLSL和HLSL着色语言,GLSL规范v4.60中未提及“mad”函数


    如何在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。