几天前我写了一篇关于 Glibc 数学代码在 AMD Zen 上通过更改使用的 FMA 实现提升了 4 倍的改进。一夜之间合并了一个新的通用 FMA 实现到 GNU C 库,现在在 AMD Zen 3 上实现了高达 12.9 倍的吞吐量提升。
Adhemerval Zanella 为 GNU C 库贡献了新的通用 FMA 实现。Zanella 在提交的补丁中解释了新的通用融合乘加(FMA)实现:
“当前的实现依赖于为不同计算设置舍入模式(首先设置为 FE_TONEAREST,然后设置为 FE_TOWARDZERO)以获得正确舍入的结果。对于大多数 CPU,这会增加显著的性能开销,因为它需要执行一个通常很慢的指令(获取/设置浮点状态),需要清空流水线,并破坏某些编译器假设/优化。
此补丁引入了一个最初由 Szabolcs 为 musl 编写的新实现,该实现主要使用整数运算。浮点运算用于引发预期的异常,而无需 fenv.h 操作。
与原始代码相比,我进行了一些修改:
* 修复了当第三个参数为 NaN 时的一些信号 NaN 问题。
* 使用 math_uint128.h 进行 64 位乘法操作。它允许编译器在可用的情况下使用 128 位类型,这可以在某些目标上(例如 MIPS64)启用一些优化。
* 修复了一个 arm32 问题,即 libgcc 例程可能不尊重舍入模式。这也可以用于其他目标来优化 int64_t 到 double 的转换。
* 在 i686 上使用-fexcess-precision=standard。
基于 musl libc 的新实现通过 Adhemerval Zanella 进行的测试显示出一些“显著的改进”:

在另一个提交中,Adhemerval Zanella 总结了为 Glibc 2.43 最近数学改进的成果:
* 从 CORE-MATH 项目中引入了额外的优化和正确舍入的数学函数,特别是 acosh、asinh、atanh、erf、erfc、lgamma 和 tgamma。
* 添加了 remainder、remaindef、frexpf、frexp、frexpl(binary128)和 frexpl(intel96)的优化实现。
* acosf、acoshf、asinhf、atan2f、atanhf、coshf、lgammaf/lgammaf_r、log10f、sinhf、sqrtf、tgammaf、y0/j0、y1/j1 和 yn/jn 的 SVID 处理已移至兼容符号,允许性能改进。
寻找这些改进以及更多改进,Glibc 2.43 预计将在 2 月份发布。
转自 GNU C Library Sees Up To 12.9x Improvement With New Generic FMA Implementation – Phoronix
Linuxeden开源社区