4. PRP与SGL数据传递机制
各位同学,今天我们来聊聊NVMe协议里一个非常核心的话题——数据怎么在主机和SSD之间传递。说白了,就是PRP和SGL这两种机制。
我记得刚接触NVMe时,看到PRP和SGL这两个缩写,第一反应是「又来了,又是两种协议打架」。但实际用下来发现,它们各有各的用武之地。今天我就把这两兄弟掰开揉碎了讲清楚。
4.1 PRP原理与构造
PRP,全称Physical Region Page,物理区域页。名字听着挺唬人,其实原理很简单。
PRP的核心思想:把物理内存划分成固定大小的页(通常是4KB),然后用一个链表把这些页串起来。NVMe控制器要读写数据时,就顺着这个链表找到每一页的物理地址。
来看一个PRP条目的结构:
PRP Entry (64位):
+-------------------------------+
| 物理地址 (63:2) | 保留位 (1:0) |
+-------------------------------+
每个PRP条目指向一个物理页的起始地址。注意,地址的低2位是保留的,因为页大小至少是4字节对齐的。
PRP列表的构造方式:
- 如果数据量小于等于一个页(4KB),只需要一个PRP条目
- 如果数据量大于一个页但小于等于两个页,需要两个PRP条目
- 如果数据量更大,就需要PRP列表了——第一个PRP条目指向数据起始页,第二个PRP条目指向一个PRP列表,这个列表里存放着后续所有页的地址
关键点:PRP列表本身也必须在物理内存中连续存放。这一点我在项目中踩过坑,后面会讲。
我画了一张图,帮大家理解PRP的链式结构:
我的经验:PRP适合小数据量的场景。比如4KB的随机读写,一个PRP条目就搞定了,开销很小。但如果你要传1MB的数据,PRP列表就会变得很长,管理起来有点麻烦。
4.2 SGL原理与构造
SGL,Scatter Gather List,分散聚合列表。这玩意儿比PRP灵活多了。
SGL的核心思想:用描述符(Descriptor)来描述每一段数据的位置和长度。每个描述符可以指向任意大小的内存块,不限于4KB页。
SGL描述符的结构:
SGL Descriptor (16字节):
+-------------------------------+-------------------------------+
| 物理地址 (63:0) | 长度 (31:0) | 类型 (15:0) |
+-------------------------------+-------------------------------+
每个描述符16字节,比PRP条目大一倍。但它能描述任意长度的数据段,灵活性大大提升。
SGL的几种类型:
- Data Block描述符:指向一块连续的数据缓冲区
- Segment描述符:指向另一个SGL段(用于链式扩展)
- Last Segment描述符:指向最后一个SGL段
- Keyed Data Block描述符:带密钥的数据块(用于加密场景)
我画了SGL的结构图:
我个人的习惯:在做大数据量传输时,我倾向于用SGL。比如视频流写入,数据块大小不一,用SGL一个描述符就能搞定,不用像PRP那样拆成很多个4KB页。
4.3 PRP vs SGL的选择策略
好了,两个机制都讲完了。那问题来了——什么时候用PRP,什么时候用SGL?
我直接给结论:
| 对比维度 | PRP | SGL |
|---|---|---|
| 条目大小 | 8字节 | 16字节 |
| 数据块大小 | 固定4KB页 | 任意大小 |
| 列表连续性 | PRP列表必须物理连续 | SGL段可以分散 |
| 适合场景 | 小数据量、固定大小传输 | 大数据量、变长传输 |
| 硬件复杂度 | 低 | 高 |
| NVMe协议支持 | 所有版本都支持 | NVMe 1.2+ 支持 |
我的选择策略:
- 4KB及以下的小IO:用PRP。一个条目搞定,简单高效。
- 4KB到1MB的中等IO:看情况。如果数据块大小是4KB的整数倍,PRP也还行。否则用SGL。
- 1MB以上的大IO:无脑选SGL。PRP列表会变得很长,管理起来很痛苦。
- 变长数据块:必须用SGL。PRP搞不定。
避坑指南:我曾经在一个项目中,用PRP传一个2.5MB的数据块。结果PRP列表有640个条目,光构造这个列表就消耗了大量CPU时间。后来换成SGL,一个段就搞定了,性能提升明显。
另外要注意,NVMe 1.2之前的设备不支持SGL。如果你要兼容老设备,只能用PRP。但现在的SSD基本都支持SGL了,所以新项目我建议直接用SGL。
嗯,PRP和SGL就讲到这里。记住一句话:小数据用PRP,大数据用SGL,变长数据必须SGL。这个原则在项目中屡试不爽。
总结:PRP和SGL都是NVMe协议中主机与SSD之间传递数据的手段。PRP简单高效但灵活性差,SGL灵活强大但开销稍大。选择哪个,取决于你的数据特征和硬件支持情况。
可可精品资料库