[AI][昇腾950] Atomic 操作说明
·
第一章:原子操作总览
1.1 四种原子操作类别
| 指令 | 总线 | 地址空间 | 返回旧值 | 用途 |
|---|---|---|---|---|
| ATOM | 系统总线 | Global Memory (OUT) | Xt | 跨核共享内存原子操作 |
| RED | 系统总线 | Global Memory (OUT) | 无 | 跨核共享内存归约 (不回读) |
1.2 原子操作通用特性
原子操作 = Read → Modify → Write (不可分割)
内存地址: ┌───────────┐
│ 原始值 V │
└─────┬─────┘
│ Read (读取旧值)
↓
┌─────────────────┐
│ Compute (计算) │ ← 不可被中断
│ V_new = V op X │
└────────┬────────┘
│ Write (写回新值)
↓
┌───────────┐
│ 新值 V_new│
└───────────┘
1.3 流水线与约束
| 属性 | ATOM/RED | ATOM_HSCB/RED_HSCB |
|---|---|---|
| 流水线 | Pipe S | Pipe S |
| DCache | 旁路 | N/A |
| Cache 一致性 | 需 DCCI + DSB | 不涉及 DCCI |
| 地址隔离 | cacheable/non-cacheable 需 4KB | — |
第二章:ATOM — 全局内存原子操作
2.1 指令语法
ATOM.op.type Xm, [Xn], Xt
| 参数 | 说明 |
|---|---|
.op |
操作类型: cas / exch / add / min / max / casp |
.type |
数据类型: u32 / s32 / u64 / s64 |
Xm |
操作数寄存器 (.cas 时同时为比较值和返回目标) |
[Xn] |
目标地址寄存器 (地址 = Xn × 8) |
Xt |
.cas: 条件写入值; 其他: 返回旧值 |
2.2 操作类型与支持矩阵
| u32 | s32 | u64 | s64 | 说明 | |
|---|---|---|---|---|---|
| .cas | ✅ | — | ✅ | — | Compare-And-Swap |
| .exch | ✅ | — | ✅ | — | 原子交换 |
| .add | ✅ | ✅ | ✅ | ✅ | 原子加 |
| .min | ✅ | ✅ | ✅ | ✅ | 原子最小值 |
| .max | ✅ | ✅ | ✅ | ✅ | 原子最大值 |
第三章:ATOM 各操作详细语义
3.1 .cas — Compare-And-Swap
功能:比较内存值与预期值,相等则写入新值,始终返回旧值。
// 伪代码
size = (.type == u32 || .type == s32) ? 32 : 64;
addr = Xn;
tmp = Mem[addr + size - 1 : addr]; // 读取当前值
cmpdata = Xm[size - 1 : 0]; // 预期值
swpdata = Xt[size - 1 : 0]; // 欲写入值
Mem[addr + size - 1 : addr] = (cmpdata == tmp) ? swpdata : tmp;
// 相等写新值, 否则不变
Xm = zeroext(tmp); // 返回旧值到 Xm
图解:
内存 [addr]: 42
Xm (期望值): 42
Xt (写入值): 99
执行: 42 == 42 ? → YES → Mem[addr] = 99
Xm = 42 (旧值)
─────────────────────────────────────
内存 [addr]: 42
Xm (期望值): 10
Xt (写入值): 99
执行: 42 == 10 ? → NO → Mem[addr] = 42 (不变)
Xm = 42 (旧值, 可以判断 CAS 是否成功)
支持类型: u32, u64
典型功能: 实现多线程可使用的 锁
3.2 .exch — 原子交换
功能:将 Xm 写入内存,返回内存中的旧值到 Xt。
tmp = Mem[addr + size - 1 : addr];
Xt = zeroext(tmp); // 返回旧值到 Xt
Mem[addr + size - 1 : addr] = Xm[size - 1 : 0]; // 写入 Xm
图解:
内存 [addr]: 100
Xm: 200
执行后:
Xt = 100 (旧值)
Mem[addr] = 200 (新值)
支持类型: u32, u64
3.3 .add — 原子加
图解:
内存 [addr]: 100
Xm: 50
执行后:
Xt = 100 (旧值)
Mem[addr] = 150 (100 + 50)
支持类型: u32, s32, u64, s64
典型用途: 计数器、累加器、Barrier
3.4 .min — 原子最小值
功能:取内存值与 Xm 的最小值写回,返回旧值到 Xt。
图解:
内存 [addr]: 100 (s32)
Xm: 80
执行后:
Xt = 100 (旧值)
Mem[addr] = 80 (min(100, 80))
─────────────────────────────────────
内存 [addr]: 50 (s32)
Xm: 80
执行后:
Xt = 50 (旧值)
Mem[addr] = 50 (min(50, 80)) 值不变
支持类型: u32, s32, u64, s64
典型用途: 全局最小值追踪、Loss 监控
3.5 .max — 原子最大值
功能:取内存值与 Xm 的最大值写回,返回旧值到 Xt。
图解:
内存 [addr]: 100 (s32)
Xm: 150
执行后:
Xt = 100 (旧值)
Mem[addr] = 150 (max(100, 150))
支持类型: u32, s32, u64, s64
典型用途: 全局最大值追踪、进度标记
第四章:RED — 全局内存归约操作
4.1 指令语法
RED.op.type [Xn], Xm
| 参数 | 说明 |
|---|---|
.op |
操作类型: add / min / max |
.type |
数据类型: u32 / s32 / f16 / bf16 / f32 |
[Xn] |
目标地址寄存器 (*Xn 表示内存地址) |
Xm |
操作数寄存器 |
4.2 操作类型与支持矩阵
| u32 | s32 | f16 | bf16 | f32 | 说明 | |
|---|---|---|---|---|---|---|
| .add | ✅ | ✅ | ✅ | ✅ | ✅ | 归约加 |
| .min | ✅ | ✅ | ✅ | ✅ | ✅ | 归约最小值 |
| .max | ✅ | ✅ | ✅ | ✅ | ✅ | 归约最大值 |
4.3 语义
*Xn = *Xn op Xm; // 直接在目标地址上归约, 不返回旧值
4.4 ATOM 与 RED 的区别
| 属性 | ATOM | RED |
|---|---|---|
| 返回旧值 | ✅ (Xt) | ❌ |
| 支持浮点 | ❌ | ✅ (f16/bf16/f32) |
| 操作种类 | cas/exch/add/min/max | add/min/max |
| 典型用途 | 锁、计数器、需回读场景 | 纯归约、累加、无需回读 |
第五章:Cache 一致性与原子操作
因为 atomic 会 bypass 掉 DCache ; 不会 bypass L2Cache ( 受Ctrl 寄存器的 hint 位控制; )
一定要注意, DCCI 与 Atomic 之间的影响
- Scalar 写 gm 数据会在DCacheLine 缓存 (通过 st_dev 指令不会在 cacheline 缓存 )
- Atomic 写 gm 数据 Bypss DCacheLine 缓存; 若要一致,需要调用dcci
5.1 为什么需要 Cache 维护
问题:
核 A Cache: │ 100 │ ← 缓存了旧值
└──┬──┘
│ ATOM.add → 直接写 Global Memory
│ (旁路 Cache)
Global Memory: │ 150 │ ← 新值
└──────┘
核 B Cache: │ 100 │ ← 缓存了旧值 (未更新!)
└──────┘
解决方案: DCCI + DSB
5.2 正确的 Cache 维护模式
// ============================================================
// 原子操作前: 确保看到最新数据
// ============================================================
pre_atomic:
DCCI X0, 1, OUT // 清理并无效化所有 OUT 相关 cache
DSB DDR // 等待清理完成
// 现在读取将直接从 Global Memory 获取最新值
ATOM.add.u32 Xm, [Xn], Xt
// ============================================================
// 原子操作后: 确保其他核可见
// ============================================================
post_atomic:
DSB DDR // 等待原子操作完成
// 其他核通过 SET_CROSS_CORE 通知或 DSB 确认
5.3 特性示意
| 同步需求 | 推荐指令 | 组合方式 |
|---|---|---|
| 互斥锁 | ATOM.cas | 自旋 CAS |
| 公平锁 | ATOM.add + LD | Ticket Lock |
| 计数器 | ATOM.add | 直接累加 |
| Barrier | ATOM.add + LD + SET_CROSS_CORE | 计数+同步 |
| AllReduce 整数 | RED.add / ATOM.add | 多核归约(有确定性风险) |
| AllReduce 浮点 | RED.add (f16/f32) | 多核浮点归约(有确定性风险) |
| 全局最大值 | RED.max / ATOM.max | 追踪极值 |
| 全局最小值 | RED.min / ATOM.min | 追踪极值 |
| 生产者-消费者 | ATOM.add + LD + DSB | 计数+读写+屏障 |
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐

所有评论(0)