主要观点:
- 对于
astcenc
的要求之一是确保编解码器的输出在不同指令集上保持一致,默认追求不变性虽有性能损失但便于下游游戏开发者。 - 不变性问题的根本原因是浮点算术,其对操作顺序敏感,会影响中间数的值、精度和累积误差,从而改变最终结果。
- 在
astcenc
的优化工作中,遇到了多个与不变性相关的问题,如浮点运算、可变宽度累加器、可变长度循环尾等,并给出了相应的解决方法。 - 除了累加器相关问题,还遇到了其他与 SIMD 实现相关的不变性问题,如编译器设置、快速近似、融合操作、标准库函数、稳定的最小/最大通道选择等,并提供了相应的注意事项和解决建议。
关键信息和重要细节:
- 浮点算术:由于浮点数字的动态精度,操作顺序的改变会影响中间数的值和精度,从而改变最终结果。严格遵循 IEEE754 规范会阻止许多涉及重新关联的编译器优化。
astcenc
中的问题及解决方法:- 问题 1:向量代码和标量代码在重新关联时行为不同,解决方法是改变参考无 SIMD 实现使用 4 宽向量,并重新排序水平操作的内部标量实现。
- 问题 2:AVX2 中向量宽度为两倍时,水平求和阶段会引入关联变化,解决方法是在所有向量化循环中使用
vec4
累加器。 - 问题 3:向量循环尾导致不变性问题,解决方法是使所有循环尾将差异累积到
vfloat4
暂存变量中,然后在满时累积到向量累加器中。 其他不变性问题:
- 编译器设置:要确保编译器符合 IEEE754 关联规则,默认建议使用
precise
浮点但禁用收缩。 - 快速近似:SIMD 指令集中的快速近似操作不精确且不一致,应避免使用。
- 融合操作:融合乘法累加操作中间精度高,不能在其他 ISA 中合理模拟,自动编译器生成的收缩应避免,但用户可手动插入保证中间值可精确表示的收缩。
- 标准库函数:标准库函数在不同硬件实现上差异较大,如需跨供应商不变性,应提供自己的数学函数实现。
- 稳定的最小/最大通道选择:在向量代码中找到数据集中最小值的索引时,需要确保返回具有最低索引的通道,可通过将索引存储在最佳误差尾数的低位来解决。
- 编译器设置:要确保编译器符合 IEEE754 关联规则,默认建议使用
- 更新记录:2021 年 2 月 26 日添加“其他不变性问题”主题;2021 年 2 月 28 日添加“标准库”主题;2024 年 8 月 25 日更新编译器设置建议,添加手动收缩和使用打包索引到尾数进行排序的注意事项。
感谢 Aras 和 Ryg 的贡献和纠正。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。