
先把两个“原子”分开否则很容易混PCIe AtomicOpPCIe 链路上的原子事务FetchAdd / Swap / CAS设备对系统内存/对端内存做“读-改-写”不被打断。NVMe 原子写 / atomic writeNVMe 命令级语义保证若干 LBA 的写“要么全成、要么全不成”是存储一致性概念不是 PCIe AtomicOp。一、PCIe 原子操作主要用在哪些场景PCIe AtomicOp 从 PCIe 3.0 起正式增强核心是让IO 设备像 CPU 一样对共享内存做无锁 RMWRead-Modify-Write。典型场景设备 ↔ 主机共享内存的同步GPU / DPU / 智能网卡更新主机内存里的队列头/尾指针无锁队列、ring buffer 生产/消费指针信号量、barrier、eventfd 类轻量同步多设备协同GPU↔GPU、NIC↔GPU、FPGA↔GPU 更新共享计数器HSA / ROCm 里用 64-bit FetchAdd 更新 dispatch id用 CAS 做无锁同步分布式 / RDMA 场景NIC 对主机内存里的统计计数器做 FetchAdd多 writer 场景避免“读-改-写”被插空IO 设备自己做无锁算法原来要靠“主机 CPU 用 LOCK 指令”或“设备读回→算→写回非原子”AtomicOp 把 RMW 压成一笔 TLP由 CompleterRC/内存控制器原子完成一句话只要“多个 PCIe 设备 / CPU / 加速器”并发访问同一块内存里的控制变量、指针、计数器、信号量又不想靠锁和往返软件协调就可能用 PCIe AtomicOp。二、NVMe 设备是否需要“发起”PCIe 原子操作普通 NVMe SSD通常不需要也不是必须标准 NVMe 模型是主机写Submission Queue (SQ)主机写Doorbell MMIO设备 DMA 读 SQ 命令设备 DMA 读写数据设备写Completion Queue (CQ)设备发 MSI-X 中断这里面SQ/CQ 本来就是“单写者”结构SQ主机写设备读CQ设备写主机读Doorbell 是普通 MMIO 写主机和设备之间不需要用 PCIe CAS/FetchAdd 来抢同一变量所以传统 NVMe SSD 不需要作为 AtomicOp Requester 去更新主机内存。但有些“高级 NVMe / 类 NVMe 设备”可能会用以下情况 NVMe 控制器可能发起 PCIe AtomicOpNVMe 用 Host Memory Buffer (HMB) 放 FTL/元数据并且多控制器/多函数共享多函数 SSD、SR-IOV NVMe多个 controller 更新同一块主机内存里的队列/引用计数/锁变量可以用 FetchAdd/CAS 避免来回加锁NVMe 支持 Shared Queue / 多 host 多 controller 架构多 port、multi-controller namespace设备内部多个核更新主机侧共享队列头尾NVMe 做 GPU/NIC 协同、计算存储、CXL/PCIe 共享内存编程比如“存储设备同时是加速器”要在主机内存里更新信号量、完成计数、task id厂商私有扩展有些 SSD 控制器用 AtomicOp 更新主机内存里的统计/telemetry/IO 调度结构但这不是 NVMe base spec 的硬性要求三、NVMe 的“原子性”更多靠这些而不是 PCIe AtomicOpNVMe 自己谈的 atomic 主要是Atomic Write Unit (AWUN / NAWUN)Atomic Write Unit Power Fail (AWUPF / NAWUPF)Atomic Compare Write可选Reservation / Namespace locking控制器内部保证多命令、掉电、FTL 映射更新的一致性这些是“写盘原子性”解决 partial write / torn write和 PCIe FetchAdd/CAS 不是一回事。四、结论PCIe AtomicOp 场景GPU/NIC/DPU/FPGA 对主机或对端内存做无锁同步、队列指针、计数器、信号量。普通 NVMe SSD一般不发起 PCIe AtomicOp它用 MMIO doorbell DMA 单写者队列模型就够了。高级 NVMeHMB、SR-IOV、multi-controller、计算存储可能会用 PCIe AtomicOp但不是 NVMe 基本模型必需。别把NVMe atomic write 和PCIe AtomicOp 混为一谈。