Merged
float类型接口性能优化 #6308
float类型接口性能优化 #6308
Merged
xuyiyangAdd on Sep 21
xuyiyang
xuyiyangCollaborators
Sep 21

描述

对 float 类型数学接口做了指令优化:

  1. 四个接口用高精度实现替代LEGACY实现
  • atanf:旧的“裁剪到 ±10000 + 多段 Taylor 展开 + fminf 选路"改为倒易约简(|x|>1 时算 1/|x|)+ 单条 8 阶 FMA 奇多项式
  • atan2f:旧的 NaN/±0/±inf 长分支链 + atanf(y/x)+d·π 改为:ax+ay 一次判 NaN → 大小排序使比值 ≤1 → 单条 minimax 多项式(对角线特判保证 π/4、3π/4 精确舍入)→ signbit 恢复符号,消除了除法前的分支
  • cbrtf:旧的“位操作指数归约到 (0.125,8) + 从 1.0 起步 5 次 Newton 迭代 + 手工拼指数"改为 exp(-2/3·log(x)) 高精度种子 + 单次 Newton 步(1 ULP),subnormal 先乘 2^24 预缩放
  • cospif:旧实现就是 cosf(x·πf)(乘 float π 有精度泄漏且走 cosf 慢归约)改为半周期约简 k=rint(2x)、r∈-0.5,0.5,奇/偶两条 z=r² 多项式按 k 奇偶选支,|x|>2^24 早退 1.0
  1. SIMT 分支友好化:早退改尾置覆盖
    asinf/acoshf/asinhf/coshf 把开头 的 early-return 特殊值分支挪到函数末尾改为 result = ... 覆盖赋值,主体无条件直落计算——消除 SIMT 锁步下的分支发散等待
  2. 换用快速内建指令
    sqrtf→__sqrtf、logf→__logf、expf→__expf、rsqrtf→1.0f/__sqrtf(asin/acos 归约、asinh、cosh 等处)

关联的Issue

https://gitcode.com/cann/asc-devkit/issues/1782

测试

SIMT API 优化对比表

SIMT API 是否优化 LEGACY 实现 高精度实现
float acosf(float x) 是 --cce-use-fast-math=true: 优化前:247.96 优化后:200.41 --cce-use-fast-math=false: 优化前:641.18 优化后:193.55 --cce-use-fast-math=true: 优化前:159.40 优化后:159.41 --cce-use-fast-math=false: 优化前:970.40 优化后:392.62
float asinf(float x) 是 --cce-use-fast-math=true: 优化前:223 优化后:156 --cce-use-fast-math=false: 优化前:230 优化后:204 --cce-use-fast-math=true: 优化前:138.84 优化后:139.04 --cce-use-fast-math=false: 优化前:653.08 优化后:331.70
float acoshf(float x) 是 --cce-use-fast-math=true: 优化前:111.76 优化后:77.21 --cce-use-fast-math=false: 优化前:400.01 优化后:371.23 --cce-use-fast-math=true: 优化前:221.94 优化后:141.20 --cce-use-fast-math=false: 优化前:221.41 优化后:141.37
float asinhf(float x) 是 --cce-use-fast-math=true: 优化前:309.12 优化后:182.53 --cce-use-fast-math=false: 优化前:596.56 优化后:183.53 --cce-use-fast-math=true: 优化前:273.28 优化后:235.49 --cce-use-fast-math=false: 优化前:611.38 优化后:551.30
float atan2f(float y, float x) 是 --cce-use-fast-math=true: 428.37 --cce-use-fast-math=false: 2608.54 --cce-use-fast-math=true: 192.10 --cce-use-fast-math=false: 548.87
float atanf(float x) 是 --cce-use-fast-math=true: 192.25 --cce-use-fast-math=false: 1476.52 --cce-use-fast-math=true: 102.88 --cce-use-fast-math=false: 311.50
float cbrtf(float x) 是 --cce-use-fast-math=true: 593.01 --cce-use-fast-math=false: 3748.54 --cce-use-fast-math=true: 优化前:136.34 优化后:124.07 --cce-use-fast-math=false: 优化前:143.17 优化后:124.71
float coshf(float x) 是 --cce-use-fast-math=true: 优化前:50.92 优化后:50.96 --cce-use-fast-math=false: 优化前:245.82 优化后:205.99 --cce-use-fast-math=true: 优化前:124.07 优化后:122.44 --cce-use-fast-math=false: 优化前:284.37 优化后:281.34
float cospif(float x) 是 --cce-use-fast-math=true: 10441.82 --cce-use-fast-math=false: 14167.28 --cce-use-fast-math=true: 优化前:154.56 优化后:95.90 --cce-use-fast-math=false: 优化前:150.14 优化后:97.48

文档更新

类型标签

likedislike
Pull Request has been successfully merged by CANN-robot.
(Thank you for xuyiyang's contribution.)
xuyiyangxuyiyangCollaborators
Sep 21 Created pull request, commit 8660c75f
atomgit-bot
atomgit-bot
Sep 21 Comments:

变更摘要

本次改动针对 impl/simt_api/math_functions_impl.h 中的 float 数学接口做性能优化,主要手段有三类:一是将 atanf、atan2f、cbrtf、cospif 四个接口由旧的 LEGACY 实现替换为高精度实现(倒易约简、minimax 多项式、对数/指数种子 + 单次 Newton 迭代、半周期约简等);二是将 asinf、acoshf、asinhf、coshf 的 early-return 特殊值分支改为尾置覆盖赋值,使主体无条件直落计算,降低 SIMT 锁步下的分支发散;三是换用快速内建指令 __sqrtf、__logf、__expf 及以 1.0f / __sqrtf(...) 替代 rsqrtf。整体属于性能优化类改动,不改变接口签名。

主要改动

  • atanf 与 atan2f 高精度实现替换 LEGACY 实现: atanf 由「裁剪到 ±10000 + 多段 Taylor 展开 + fminf 选路」改为 |x| > 1 时做倒易约简 1/|x|,再用单条 x^2 奇多项式(fmaf 链)求值并恢复 π/2 补角;atan2f 由「NaN/±0/±inf 长分支链 + atanf(y/x) + d·π」改为 ax + ay 一次判 NaN、按大小排序使比值 ≤1、单条 minimax 多项式(对角线特判 π/4 与 3π/4)、最后用 signbit 恢复符号。
  • cbrtf 改为对数/指数种子 + 单次 Newton 步: 旧实现「位操作指数归约到 (0.125,8) + 从 1.0 起步 5 次 Newton 迭代 + 手工拼指数」被替换为 exp(-2/3·log(x)) 生成高精度种子 y 后仅做一次 Newton 步,subnormal 输入先乘 2^24 预缩放并减去 24·ln2,0/inf/NaN 直接透传。
  • cospif 改为半周期约简多项式实现: 旧实现 cosf(x * ASCRT_PI_F) 改为 k = rint(2x)、r = x - k/2 ∈ [-0.5, 0.5] 的约简,按 k 奇偶在偶支多项式 c 与奇支多项式 s 之间选支,|x| > 2^24 覆盖为 1.0f,inf/NaN 分别覆盖为 x * 0.0f 与 x。
  • asinf、acoshf、asinhf、coshf 的分支结构改为尾置覆盖: 将开头的 fabsf(x) > 1、x < 1、ax == ASCRT_INF_F、ax < 1.0e-8f、__isnan(ax) || __isinf(ax) 等 early-return 特殊值分支移到函数末尾,改为对 result 变量覆盖赋值后统一 return,使主体计算路径无条件执行。
  • 换用快速内建指令: 在 asinf、asinhf、acoshf、coshf 及 __internal_asin_acos_reduced_arg 中,将 sqrtf 改为 __sqrtf、logf 改为 __logf、expf 改为 __expf,并把 rsqrtf(half_one_minus_abs) 改为 1.0f / __sqrtf(half_one_minus_abs)。
likedislike
Incorrect?
atomgit-bot
atomgit-bot
Sep 21 Comments:

代码审查

✅ 未发现问题

likedislike
Incorrect?
CANN-robotCANN-robotCollaborators
Sep 21 Added label: stat/needs-squash
CANN-robotCANN-robotCollaborators
Sep 21 Added label: cann-cla/yes
99 messages are collapsed here。 See more
wulinyuCollaborators
Sep 23 Comments:

/lgtm

likedislike
CANN-robotCANN-robotCollaborators
Sep 23 Added label: lgtm
wulinyuCollaborators
Sep 23 Comments:

/approve

likedislike
CANN-robotCANN-robotCollaborators
Sep 23 Added label: approved
CANN-robotCANN-robotCollaborators
Sep 23 Merged pull request