附录与参考资料 - 第451页
我们现在进入的是 《NVM Express® Base Specification 2.0b》第 B.3 节:执行 Fused 操作(Fused Operation) 的深入中文解析。
📌 B.3 执行 Fused Operation(复合操作执行)
🔍 这节的核心:以 Compare + Write 为例,讲解主机如何构建和执行一个 Fused Command(复合命令)。
✅ Fused Command 是什么?
Fused Command(复合命令)是 两个连续的 NVMe 命令组合在一起原子执行 的机制,通常用于:
- Compare + Write 场景(最典型);
- 保证原子性 —— 若 Compare 失败,Write 不会执行;
- 多用于数据库或日志写入操作(比如 WAL 日志写入)。
📘 示例背景设定:
- 复合操作:Compare ➕ Write;
- 总数据量:16 KiB;
- 每个 LBA 块大小:4 KiB;
- 所以总共涉及 4 个逻辑块;
- 未启用端到端数据保护(E2E Protection);
- 用到了两个命令槽(CMD0 和 CMD1);
- 同一个 Submission Queue 中的连续槽位。
🔧 CMD0:Compare 命令构建
字段 | 设置 | 说明 |
---|---|---|
CDW0.OPC |
05h |
操作为 Compare |
CDW0.FUSE |
01b |
表示此命令是 Fused 操作的 第一个命令 |
CDW0.CID |
任意可用 ID | 例如 0xA1 |
NSID |
指定命名空间 ID | 如 1h |
PRP1/PRP2 |
数据缓冲区的物理地址 | 用于比较的数据 |
CDW10–CDW15 |
指令特定参数,比如起始 LBA、数量等 |
🧩 CMD1:Write 命令构建
字段 | 设置 | 说明 |
---|---|---|
CDW0.OPC |
01h |
操作为 Write |
CDW0.FUSE |
10b |
表示此命令是 Fused 操作的 第二个命令 |
CDW0.CID |
可用 CID,不等于 CMD0 的 CID | 例如 0xA2 |
NSID |
与 CMD0 相同的命名空间 ID | |
PRP1/PRP2 |
实际写入的数据的物理地址 | |
CDW10–CDW15 |
与 Compare 相同的起始 LBA 与范围 |
🔄 命令提交顺序(关键点):
- 先写入 CMD0(Compare)
- 再写入 CMD1(Write)
- 最后 Doorbell 提交这两个命令
⚠️ 顺序不能搞反,否则命令结构将不被识别为合法的 Fused Pair。
📎 FUSE 字段说明:
FUSE 值 | 含义 |
---|---|
00b |
非复合命令(默认) |
01b |
Fused Pair 的 第一条命令 |
10b |
Fused Pair 的 第二条命令 |
11b |
保留值(非法) |
✅ 成功与否如何判断?
- 如果 Compare 成功,控制器会继续执行 Write;
- 如果 Compare 失败,Write 命令会被自动取消;
- 控制器将对两条命令分别填入 Completion Queue Entry;
- 可以根据
SQE.CID
和CQE.Status
判断每条命令的执行状态。
📌 适用场景建议
- 多用于数据库系统要求“先验证再写入”的高一致性场景;
- 避免逻辑层多余的锁机制或重试逻辑;
- 强烈建议搭配 非易失性内存 或 写缓存保护机制(如 FLUSH) 使用。
需要我帮你写一段 构造 Fused Compare + Write 命令的示例代码(如 C/C++ 伪代码) 来更直观地展示整个过程吗?也可以做成流程图形式辅助理解。你希望用哪种形式继续?