Merged
float类型数学接口性能优化 #6829
float类型数学接口性能优化 #6829
Merged
xuyiyangAdd on 19 days ago
xuyiyang
xuyiyangCollaborators
19 days ago

描述

本 PR 针对 impl/simt_api/math_functions_impl.h 中的 float 数学接口做性能优化,核心手段是精简分支与指令流:新增 Cody-Waite 专用余弦实现 __internal_cosf_cody_waite 供已知落在 Cody-Waite 有效区间内的调用方使用;将 j0f、y0f、y1f 等贝塞尔/诺依曼函数的特殊值判断改为「先主路径计算、后统一修正」的结果变量写法以避免提前返回;并重写 rnorm4df 与 fmodf 的归一化/累加逻辑,用位运算替代循环。

主要改动

新增 __internal_cosf_cody_waite: 提供仅走 Cody-Waite 弧度规约的余弦实现,在 |x| <= 71476.0625f 范围内与 cosf 结果一致,使调用方可将 Payne-Hanek 阈值分支移出指令流。
贝塞尔/诺依曼函数改用专用余弦: __internal_j0f_huge_range、__internal_j1f_huge_range、__internal_y0f_huge_range、__internal_y1f_huge_range 中的 cosf 调用统一替换为 __internal_cosf_cody_waite,并补充 r - pi/4 等参数落在 Cody-Waite 区间内的注释说明。
特殊值处理路径重构: j0f、y0f、y1f 移除开头的 NaN/Inf/符号提前返回,改为先计算 result 再在末尾统一覆盖特殊值;j1f 的 -inf 分支改用 __internal_with_sign_bit(0.0f, x) 生成有符号零。
rnorm4df 简化归一化流程: 去掉幅值排序与次正规数临时缩放逻辑,改为按输入顺序用 fmaf 直接累加缩放后的平方和,并将 rsqrtf 替换为 1.0f / __sqrtf 再叠加一次牛顿迭代。
fmodf 重写规约逻辑: 用 __asc_uint_floor_log2 替代循环完成尾数归一化,引入 exact 标志与 fits 判断统一处理精确零余数,并在最后以 ux < uy 覆盖返回 x 本身。

关联的Issue

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

测试

SIMT API 是否优化 LEGACY实现 高精度实现
float y0f(float x) 是 --cce-use-fast-math=true: 5110
--cce-use-fast-math=false: 7346.25
--cce-use-fast-math=true: 4281
--cce-use-fast-math=false: 6474.88
float y1f(float x) 是 --cce-use-fast-math=true: 4421.5
--cce-use-fast-math=false: 9298.12
--cce-use-fast-math=true: 3118
--cce-use-fast-math=false: 6143
float ynf(int n, float x) 是 --cce-use-fast-math=true: 14972
--cce-use-fast-math=false: 24897
--cce-use-fast-math=true: 13806.11
--cce-use-fast-math=false: 24883.89
float j0f(float x) 是 --cce-use-fast-math=true: 3250
--cce-use-fast-math=false: 5425.12
--cce-use-fast-math=true: 3129
--cce-use-fast-math=false: 4967.12
float j1f(float x) 是 --cce-use-fast-math=true: 3416.50
--cce-use-fast-math=false: 6276.34
--cce-use-fast-math=true: 3141
--cce-use-fast-math=false: 6006.5
float jnf(int n, float x) 是 --cce-use-fast-math=true: 36910.75
--cce-use-fast-math=false: 113925.75
--cce-use-fast-math=true: 36144.75
--cce-use-fast-math=false: 113130.88
float rnorm4df(float a, float b, float c, float d) 是 --cce-use-fast-math=true: 160
--cce-use-fast-math=false: 335
--cce-use-fast-math=true:
优化前:240.73    优化后:215
--cce-use-fast-math=false:
优化前:741.85    优化后:544
float fmodf(float x, float y) 是 --cce-use-fast-math=true: 4815.73
--cce-use-fast-math=false: 4814.39
--cce-use-fast-math=true:
优化前:6032.73    优化后:5552.19
--cce-use-fast-math=false:
优化前:6001.69    优化后:5565.00

文档更新

类型标签

likedislike
Pull Request has been successfully merged by CANN-robot.
(Thank you for xuyiyang's contribution.)
xuyiyangxuyiyangCollaborators
19 days ago Created pull request, commit 45db6338
atomgit-bot
atomgit-bot
19 days ago Comments:

变更摘要

本 PR 针对 impl/simt_api/math_functions_impl.h 中的 float 数学接口做性能优化,核心手段是精简分支与指令流:新增 Cody-Waite 专用余弦实现 __internal_cosf_cody_waite 供已知落在 Cody-Waite 有效区间内的调用方使用;将 j0f、y0f、y1f 等贝塞尔/诺依曼函数的特殊值判断改为「先主路径计算、后统一修正」的结果变量写法以避免提前返回;并重写 rnorm4df 与 fmodf 的归一化/累加逻辑,用位运算替代循环。

主要改动

  • 新增 __internal_cosf_cody_waite: 提供仅走 Cody-Waite 弧度规约的余弦实现,在 |x| <= 71476.0625f 范围内与 cosf 结果一致,使调用方可将 Payne-Hanek 阈值分支移出指令流。
  • 贝塞尔/诺依曼函数改用专用余弦: __internal_j0f_huge_range、__internal_j1f_huge_range、__internal_y0f_huge_range、__internal_y1f_huge_range 中的 cosf 调用统一替换为 __internal_cosf_cody_waite,并补充 r - pi/4 等参数落在 Cody-Waite 区间内的注释说明。
  • 特殊值处理路径重构: j0f、y0f、y1f 移除开头的 NaN/Inf/符号提前返回,改为先计算 result 再在末尾统一覆盖特殊值;j1f 的 -inf 分支改用 __internal_with_sign_bit(0.0f, x) 生成有符号零。
  • rnorm4df 简化归一化流程: 去掉幅值排序与次正规数临时缩放逻辑,改为按输入顺序用 fmaf 直接累加缩放后的平方和,并将 rsqrtf 替换为 1.0f / __sqrtf 再叠加一次牛顿迭代。
  • fmodf 重写规约逻辑: 用 __asc_uint_floor_log2 替代循环完成尾数归一化,引入 exact 标志与 fits 判断统一处理精确零余数,并在最后以 ux < uy 覆盖返回 x 本身。
likedislike
Incorrect?
atomgit-bot
atomgit-bot
19 days ago Comments:

代码审查

审查结论

已审查文件

  • impl/simt_api/math_functions_impl.h(唯一改动文件,已逐段审查)
    • 发现 2 个问题(下表),其余改动区域经核对未发现缺陷。

发现清单

# 优先级 位置 问题
1 P1 2564-2579 j0f 的 NaN/Inf 特殊值处理被 if/else 提前 return 变为不可达死代码,result 未初始化;±Inf/NaN 语义回归,+Inf 还会落入 huge_range 触发 PH 越界读
2 P2 2644-2655 y0f/y1f 把 isinf 判断移到分支之后,+Inf 会先执行 huge_range → payne_hanek_radian_reduction(Inf) → two_over_pi_table[6] 数组越界读(表长 6)

未发现问题的改动区域(核对通过)

  • 新增 __internal_cosf_cody_waite(874-889):与 cosf 在 |x| <= 71476.0625f 内逐行等价;四个 huge_range 调用点(2124/2153/2244/2282)的实参 r - kπ/4(r∈[0,2π))均深在 Cody-Waite 阈值内,替换安全。
  • j1f 的 Inf 处理改为 __internal_with_sign_bit(0.0f, x)(2592):与原手写位操作语义一致。
  • y1f 次正规分支(2688-2690)挪到分支后是有意修复(原位置被随后的 < 1.2f 分支覆盖),结果与原意一致。
  • rnorm4df(4297-4336):去掉次正规抬升、改用 1.0f / __sqrtf,与未改动的兄弟实现 rnorm3df 完全一致(消除既有分歧,未引入新分歧)。
  • fmodf(5196-5293):重写为与 musl 定点长除法等价的形式,|x|<|y|、|x|==|y|、x=0、y=Inf、次正规域、exact-select 等边界逐例核对结果正确,__asc_uint_floor_log2 的下标范围 [0,23] 有守卫。

总体风险判断

改动以性能优化为主(消除多余分支/PH 表索引),核心数值路径基本正确;但 j0f/y0f/y1f 的“分支重排”把特殊值判断放到分支之后,造成一处明确的逻辑回归(死代码 + 特殊值语义丢失)以及一处新可达的越界读路径,建议在合入前修正。其余改动风险较低。

类型 数量
🔴 阻塞 1
🟡 建议 0

⛔ 需要修改

likedislike
Incorrect?
CANN-robotCANN-robotCollaborators
19 days ago Added label: stat/needs-squash
CANN-robotCANN-robotCollaborators
19 days ago Added label: cann-cla/yes
62 messages are collapsed here。 See more
louyuxuanCollaborators
17 days ago Comments:

/lgtm

likedislike
xuyiyangxuyiyangCollaborators
17 days ago Resolved final issue
wulinyuCollaborators
17 days ago Comments:

/approve

likedislike
CANN-robotCANN-robotCollaborators
17 days ago Added label: lgtmapproved
CANN-robotCANN-robotCollaborators
17 days ago Merged pull request