简体   繁体   English

有没有办法在Vulkan SPIR-V中使用OpenCL C mad函数?

[英]Is there a way to use OpenCL C mad function in Vulkan SPIR-V?

As we know, there's at least 2 ways to calculate a * b + c : 众所周知,至少有两种方法可以计算a * b + c

  1. ret := a*b; ret := ret + c;

  2. ret := fma(a, b, c);

But in OpenCL C, there's a third function called "mad" that trades precision for performance. 但是在OpenCL C中,还有第三个函数“ mad”,它将精度与性能进行了权衡。

In the LunarG sdk, the default SPIR-V compiler compiles the GLSL and HLSL shading languages and the "mad" function is not mentioned in GLSL spec v4.60. 在LunarG sdk中,默认的SPIR-V编译器将编译GLSL和HLSL着色语言,并且GLSL规范v4.60中未提及“ mad”功能。

How do I use "mad" function in Vulkan? 如何在Vulkan中使用“疯狂”功能?

There's a bit of misunderstanding here. 这里有些误会。

Fused multiply add does not mean less precision. 融合的乘法加法并不意味着精度降低。 What it may mean is a slightly different number than if you applied a multiply then add vs fma, because of the internal hardware precision differences kept between steps of the operation. 由于在操作步骤之间保持内部硬件精度差异,因此与使用乘法然后加上与fma相比,该数字可能略有不同。 For this reason in some API's/languages automatic FMA isn't enabled by default, and only comes when fast-math or specific flag is used in your compiler. 因此,在某些API /语言中,默认情况下未启用自动FMA,只有在编译器中使用了快速运算符或特定标志时,才会启用FMA。 There may be systems where it results in poorer precision, but that isn't what it implies. 可能在某些系统中精度会降低,但这并不是它的含义。

In SPIR-V however, while there doesn't appear to be a specific instruction for FMA, the spec explicitly predicts and allows for it post SPIR-V -> gpu assembly compilation. 但是,在SPIR-V中,虽然似乎没有针对FMA的特定说明,但该规范明确预测并允许在SPIR-V-> gpu汇编编译之后进行。 It even has a NoContraction decoration in the language. 它甚至在该语言中都具有NoContraction装饰。

NoContraction Apply to an arithmetic instruction to indicate the operation cannot be combined with another instruction to form a single operation. NoContraction应用于算术指令,以指示该操作不能与另一条指令合并以形成单个操作。 For example, if applied to an OpFMul, that multiply can't be combined with an addition to yield a fused multiply-add operation. 例如,如果应用于OpFMul,则该乘法不能与加法运算相结合以产生融合的乘法加法运算。 Furthermore, such operations are not allowed to reassociate; 此外,不允许此类操作重新关联; eg, add(a + add(b+c)) cannot be transformed to add(add(a+b) + c). 例如,add(a + add(b + c))无法转换为add(add(a + b)+ c)。

Note that SPIR-V is not the end all be all of your shader. 请注意,SPIR-V并不是着色器的全部。 It is only a portable intermediary representation of your shader, which is then further compiled by your vendors vulkan drivers. 它只是着色器的可移植中间表示,然后由供应商vulkan驱动程序进一步编译。 No machine runs SPIR-V directly. 没有机器直接运行SPIR-V。 These kinds of optimizations are left to the driver to perform, rather than to the programmer. 这类优化留给驱动程序执行,而不是由程序员执行。 You can generally assume that such an optimization will occur under the appropriate conditions, this is the same for other programming languages that lack a explicit FMA builtin. 您通常可以假设这样的优化将在适当的条件下发生,这对于缺少显式FMA内置功能的其他编程语言是相同的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM