已关闭
[Bug-Report|缺陷反馈]: Atlas 950 / CANN 9.1.0 下多核 SIMT-VF 局部 UB sketch 聚合数据丢失 #36
m0_66826439创建于  7 天前关闭于  6 天前
m0_66826439
m0_66826439
7 天前 创建

开发 9 月社区任务「hyperloglog容器开发(950)」(对标 NVIDIA cuCollections hyperloglog,使用仓库 BloomFilter 的 SIMT 工程范式)时,需要复刻 cuCollections 的 Add 路径:所有线程按网格 stride 处理 key,先在每个 AIV 核各自的局部 scratch(UB)中做 sketch 聚合(原子字节位 max),块结束再合并回全局。实测在 Atlas 950 + CANN 9.1.0 下,单核(1 block × 1024 线程)完全正确,但多核(8 block × 1024 线程)并发时每个 block 的局部 UB 聚合大量丢失:8192 字节的局部 sketch 仅约 1/8(≈1024 字节)的寄存器被更新,其余仍为 0;核数越多丢失越严重。 这导致 HLL Add 只能退化为逐 key 全局原子更新(1e8 次约 2.8~5.2ms),无法达到任务书性能基线 0.4×(8KB 档预算≈0.79ms)。

Environment / 环境信息(必填)

  • 昇腾硬件:Atlas 950(Ascend950PR),单卡,128GB HBM(npu-smi info 见 Ascend950PR)
  • CANN:9.1.0(/usr/local/Ascend/cann-9.1.0
  • 编译器:Bisheng(clang 15.0.5,/usr/local/Ascend/cann-9.1.0/tools/ccec_compiler/bin/bisheng),-x asc --npu-arch=dav-3510 -O3
  • 头文件:kernel_operator.h + simt_api/device_atomic_functions.h + simt_api/device_sync_functions.h + simt_api/cpp/kernel_simt_atomic_intf.h
  • 启动方式:Kernel<<<numBlocks, launchBytes, aclrtStream>>>(...),内部 AscendC::Simt::VF_CALL<...>(AscendC::Simt::Dim3{1024}, ...)

Steps to reproduce the issue / 重现步骤(必填)

构造最小内核(每 block):

  1. 在局部 UB 申请 8192B sketch(已分别尝试:静态 __ubuf__ uint8_t ls[8192]、动态 get_imm(0)、动态+blockIdx*8192 偏移);
  2. 各线程按 globalThreadIndex stride 清零该 8192B;
  3. asc_syncthreads()
  4. 各线程网格步长遍历 1e6 个 uint32 key:HashRank(复用仓库 hash_functions 的 xxhash64)→ 对该 block 自己的 UB sketch 做 32 位字 CAS 的字节位 max 更新(同一寄存器被多线程竞争);
  5. asc_syncthreads()
  6. 每 block 把局部 sketch 排空到不相交的 GM 区(out[blockIdx*8192 + i]),host 读取并与"宿主全量参考 sketch"(逐 key 求寄存器 max)逐字节比对。

已尝试的变体(均无效,结果完全相同:每个 block 约 7168/8192 的寄存器仍为 0):

  • 静态 __ubuf__ 数组;
  • 动态 get_imm(0)launchBytes = 8192
  • 动态 get_imm(0)launchBytes = 8 × 8192
  • 动态 get_imm(0) + blockIdx × 8192(per-block 偏移寻址);
  • init 与 update 之间、update 与 drain 之间各调用 两次 asc_syncthreads()

对照验证(同模型下可用的原语,均正常):

  • 8 block 各自对单字(4B)UB 原子 max:每块独立得到 1023,正确;
  • 全局内存(GM)原子字节位 max、32B 向量读、单 block 内 asc_syncthreads:均正常;
  • 仓库 BloomFilter 现有的高性能 Add 在此 CANN 下刻意采用 GM 工作区 route/apply 两段式,未使用多块 UB 屏障聚合。

Describe the expected behavior / 预期结果(必填)

期望:多核并发时,每个 AIV 核在其各自的局部 UB 上进行的(原子字节位 max)聚合能够正确保留全部更新(与单核结果一致),从而 HLL/类似容器可以把每核局部聚合与最后的 GM 合并路径作为高性能 Add 方案使用(对标 cuCollections 的 per-block 共享内存 sketch)。

8 block × 1024 线程、n=1e6、precision=13、每块 8192B 局部 sketch,与宿主参考逐字节比对结果:

block 0: same=73   bad=8119  zero=7168
block 1: same=55   bad=8137  zero=7168
block 2: same=76   bad=8116  zero=7168
block 3: same=65   bad=8127  zero=7168
block 4: same=66   bad=8126  zero=7168
block 5: same=69   bad=8123  zero=7168
block 6: same=70   bad=8122  zero=7168
block 7: same=76   bad=8116  zero=7168

单核对照:全部正确(bad=0)。

Special notes for this issue / 备注(选填)

  • HyperLogLog 任务相关:实现与测试已完成、官方 1280 功能用例全绿,仅因上述限制使 Add 性能无法达到 0.4× 标杆;其余操作均达标。完整设计与自测报告将随任务交付。
  • 想请教社区:多 block 并发时 per-core 局部 UB 的正确使用方式(声明/寻址/同步)是否是"每 block 各自一份"?还是此 CANN 版本对多块 SIMT-VF 的局部 UB 有已知限制/需要特定开关(如 SPLIT_CORE_VEC、动态 UB 预留)?若有修复版本,请告知最低版本号。
  • 可提供最小复现代码(编译即跑的探针)与完整实验记录。
likedislike
goodpeople233成员
7 天前 评论:

当前从描述看未能理解您的问题,能否重新描述下您的具体问题?比如对某个具体SIMT接口使用有疑问或哪种使用方式有疑问?还是对某个具体场景的运作逻辑有疑问?

likedislike
m0_66826439
m0_66826439
6 天前 评论:

当前从描述看未能理解您的问题,能否重新描述下您的具体问题?比如对某个具体SIMT接口使用有疑问或哪种使用方式有疑问?还是对某个具体场景的运作逻辑有疑问?

@goodpeople233
就是想确认一下:AIV 单核内多个 SIMT 线程并发对 UB 的不同地址做 32-bit atomic CAS(用于 byte max)时,除了 asc_syncthreads() 还需要额外同步/写回吗,还是这种 UB 多地址小粒度原子聚合本身就不支持?
我弄了个复现脚本,您那边看看?
对照:
1 核 × 1024 线程:8KB 私有 UB sketch 全部 8192 字节与参考一致;
8 核 × 1024 线程:每块只剩 ~1/8(1024 字节)被更新且值正确,其余 7168 字节从未写入、保持 0——更新在多核下静默丢失约 7/8,核数越多丢得越多。

95a708a0dd8540078a9b7fe90cf381da.zip

likedislike
goodpeople233成员
6 天前 评论:

@m0_66826439 已确认非接口不支持及需要额外同步/写回,当前附件有问题主要为脚本bug,初步确认到LocalSketchKernel的stride计算有误,请进一步排查。

likedislike
m0_66826439
m0_66826439
6 天前 评论:

@m0_66826439 已确认非接口不支持及需要额外同步/写回,当前附件有问题主要为脚本bug,初步确认到LocalSketchKernel的stride计算有误,请进一步排查。

@goodpeople233

豪德,我去看看

likedislike
m0_66826439
m0_66826439
6 天前 评论:

@goodpeople233 我好像发现问题了!!谢谢解答,确实是来资于LocalSketchKernel 这个kenel的问题,我改为按块内线程号遍历后 1 核与 8 核均 100% 正确,另外实测该聚合路径并不比逐 key GM 原子快(56 核约 0.56x),性能结论不变,谢谢指正。麻烦帮忙关闭下

likedislike
goodpeople233成员
6 天前 评论:

/close

likedislike
CANN-robotCANN-robot成员
6 天前 issue状态由 待办的 改变为 已完成
CANN-robotCANN-robot成员
6 天前 关闭了 issue