float 的性能成本 ↔︎ Metal 中的一半转换

Performance cost of float ↔︎ half conversion in Metal

我有一个基于 Metal 的 Core Image 卷积核,它使用 half 精度变量来跟踪总和和权重。但是,我现在发现 16 位 half 的范围在某些情况下是不够的,这意味着我需要 32 位 float 用于某些变量。

现在我想知道什么是更高性能的:

前者意味着所有算术都是以 32 位精度执行的,尽管只有某些操作需要它。

是否有任何文档或基准我可以 运行 找到 float ↔︎ half 在 Metal 中转换的成本?

我相信你应该选择选项 A:

use half as much as possible (for the samplers and most local vars) and only convert to float when needed (which means quite a lot, inside the loop)

基于题为“高级金属着色器优化”的 WWDC 2016 演讲中的讨论链接 here

在 17:17-18:58 左右是该主题的相关部分。演讲者 Fiona 提到了一些重要的事情:

  1. A8 及更高版本的 GPU 有 16 位寄存器,这意味着 32 位浮点格式(如 float)使用 两倍 的寄存器,这意味着两倍的带宽、能量等。因此使用 half 可以节省寄存器(这总是好的)和能量
  2. 在 A8 和更高版本的 GPU 上,“数据类型转换通常 自由 甚至在 float 和 half 之间 [强调已添加]。” Fiona 甚至提出了您可能会问自己的问题,涵盖了我认为您对所有转换感兴趣的内容,并说它可能仍然很快,因为转换是免费的。此外,根据金属着色语言规范版本 2.3(第 218 页)

For textures that have half-precision floating-point pixel color values, the conversions from half to float are lossless

这样您就不必担心精度也会丢失。

该部分还有其他一些值得研究的相关要点,但我相信这足以证明选择选项 A 是合理的