如何在Vulkan中使用现代GLSL获取16位浮点数?

5

看起来在某个时候,Nvidia有一个扩展允许半浮点值用于OpenGL 1.1,但显然自那时以来,*现代GLSL规范已经在某个时候收回了half

今天我可以毫无问题地使用CUDA中的16位浮点值(链接1),NVIDIA在硬件上支持16位浮点值不应该是问题,并且他们似乎在HLSL中支持它们,甚至相互矛盾地在HLSL交叉编译到SPIR-V时也支持它们,而GLSL则不支持。看起来,SPIR-V具有支持16位浮点数所需的所有基元(主要扩展名为KHR),因此没有理由禁止我使用它们。
我不确定为什么,尽管我有一张Nvidia显卡,但我无法利用16位浮点运算,显然如果我想利用它,我必须使用AMD或完全切换API。一定有某种方法可以同时使用真正的16位浮点值吧?
我并不是在询问主机到设备分配的缓冲区(即顶点缓冲区)。是的,你可以使用KHR扩展将它们分配为16位浮点数,并且不会有太多问题,但我担心的是在实际着色器中使用16位浮点数,而不是被强制转换为32位浮点数的16位浮点数。

我假设您已经意识到,在所有帕斯卡家族消费级显卡上,FP16操作的吞吐量非常低,因此最好从FP16缓冲区中读取,但在FP32中进行计算。 - njuffa
哇,我真没意识到 Nvidia 在消费级 fp16 性能方面没有做太多工作,他们自 CUDA 7.0 以来一直在宣传“fp16 将提高性能!”。虽然 PTX 会 JIT fp16 来使用 fp16 单元和 fp32 单元,但这些统计数据还是有点奇怪。然而,看看 CUDA 8.0 的混合精度,他们特别提到了 P 系列指令,而不是所有 GPU 都可用的指令。 - Krupip
在 Volta 中,@njuffa 似乎认为张量核心也会用于消费级别的GPU,否则他们的神经网络降噪滤波器将不再相关。张量核心是4x4x4 16位浮点矩阵乘法单元。 - Krupip
1
你提供的博客文章具体讨论了P100,这是唯一具有高FP16操作吞吐量的Pascal系列GPU。 P100不是任何消费级零件的基础,它仅在高端Quadro和Tesla零件中发现。目前没有人知道Volta消费级零件会是什么样子,或者是否实际上会有Volta消费级零件(一些谣言称消费级零件将使用不同的架构)。在我看来,FP16作为存储格式非常有用,可以减少带宽要求,但在NVIDIA 消费者 GPU的巨大宇宙中,对于计算而言并不是非常有用。 - njuffa
1个回答

6

VK_KHR_shader_float16_int8通过SPIR-V和Vulkan(以及8位整数)在着色器中暴露FP16功能。该扩展在Vulkan 1.2中被提升为核心(作为可选功能)。此功能仅在着色器内启用计算,而不是在着色器接口(顶点着色器输入、UBO等)中使用16位浮点数。

SPV_AMD_gpu_shader_half_float将Float16功能暴露给SPIR-V,但相应的Vulkan扩展VK_AMD_gpu_shader_half_float实际上没有在Vulkan中启用类似的功能。因此,您无法真正使用它。这最终得到了解决。


是的,编译器 glslang 可以输出具有 Float16 功能的 SPIR-V。但 Vulkan 规范没有提供任何功能或扩展来暴露该功能。因此,没有 Vulkan 实现可以使用使用 Float16 的着色器。是的,它公开了 16 位浮点数存储的功能,但附录 A 从未Float16 提及为一项功能。它具有像 StorageBuffer16BitAccessStoragePushConstant16 这样的功能,但不包括 Float16 本身。16 位存储仅适用于获取和设置数据,而不适用于数据的内部着色器处理。 - Nicol Bolas
但是你放在那里的链接不是真的展示了半浮点着色器的扩展吗? - Krupip
但是似乎标准与扩展都允许这样做?https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VK_AMD_gpu_shader_half_float - Krupip
@pmw1234:OP明确表示他们不是在询问如何在接口类型中使用16位值。我已更新帖子,以反映在着色器内操作时使用16位值的当前状态。 - Nicol Bolas
@NicolBolas 这只是在研究 Vulkan 上的 fp16 时出现的帖子之一,我只是想保持它的最新状态,仅此而已。 - pmw1234
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接