蛋蛋读NVMe之一:为什么刘备需要NVMe

上回书说道,NVMe有三宝:SQ,CQ和DB。接下来我们就详细的看看这吉祥三宝。

Host往SQ中写入命令, SSD往CQ中写入命令完成结果。SQ与CQ的关系,可以是一对一的关系,也可以是多对一的关系,但不管怎样,他们是成对的:有因就有果,有SQ就必然有CQ。

有两种SQ和CQ,一种是Admin,另外一种是I/O,前者放Admin命令,用以Host管理控制SSD,后者放置I/O命令,用以Host与SSD之间传输数据。”你挑着担,我牵着马”(西游记的节奏呀),Admin SQ/CQ 和I/O SQ/CQ各司其职,你不能把Admin命令放到I/O SQ中,同样,你也不能把I/O命令放到Admin SQ里面。如果你不信这个邪,可以不遵守这个规矩试试,看看会发生什么,反正后果自负。

正如上图所示,系统中只有一对Admin SQ/CQ,它们是一一对应的关系;I/O SQ/CQ却可以很多,多达65535(64K减去一个SQ/CQ)。行政人员少,干活的人多,很多公司都是这样的吧,所以Admin SQ/CQ少,I/O SQ/CQ多就不难理解了。Host端每个Core可以有一个或者多个SQ,但只有一个CQ。给每个Core分配一对SQ/CQ好理解,为什么一个Core中还要多个SQ呢?一是性能需求,一个Core中有多线程,可以做到一个线程独享一个SQ;二是QoS需求,什么是QoS?Quality of Service,服务质量。脑补一个场景,蛋蛋一边看小电影,同时迅雷在后台下载小电影,由于电脑配置差,看个小电影都卡。蛋蛋最讨厌看小电影的时候卡顿了,因为你刚刚燃起的激情会被那个缓冲浇灭。所以,蛋蛋不要卡顿!怎么办?NVMe建议,你设置两个SQ,一个赋予高优先级,一个低优先级,把看小电影所需的命令放到高优先级的SQ,迅雷下载所需的命令放到低优先级的SQ,这样,你那破电脑就能把有限的资源优先满足你看小电影了。至于迅雷卡不卡,下载慢不慢,这个时候已经不重要了。能让蛋蛋舒舒服服的看完一个小电影,就是好的QoS。

实际系统中用多少个SQ,取决于系统配置和性能需求,可灵活设置I/O SQ个数。关于系统中I/O SQ的个数,NVMe白皮书给出如下建议:

作为队列,每个SQ和CQ都有一定的深度:对Admin SQ/CQ来说,其深度可以是2-4096(4K);对I/O SQ/CQ,深度可以是2-65536(64K)。队列深度也是可以配置的。

SQ/CQ的个数可以配置,每个SQ/CQ的深度又可以配置,因此NVMe的性能是可以通过配置队列个数和队列深度来灵活调节的。NVMe太牛了吧,想胖就胖,想瘦就瘦;想高就高,想矮就矮,整一孙悟空呀!我们已经知道,AHCI只有一个命令队列,且队列深度是固定的32,就凡人一个,和NVMe相比,无论是在命令队列广度还是深度上,都是无法望其项背的;NVMe命令队列的百般变化,更是AHCI无法做到的。说到百般变化,我突然又想到一件残忍的事情:PCIe也是可以的。一个PCIe接口,可以有1,2,4,8,12,16,32条lane!SATA都要哭了,单挑都挑不过你,你还来群殴我。总之AHCI/SATA和NVMe/PCIe 这么一比较,画面太美,蛋蛋不敢看。

蛋蛋在这里总是贬低AHCI/SATA,有人要说蛋蛋忘恩负义,过河拆桥。怎么说?想当年,你SSD刚出来的时候,要不是AHCI/SATA收留了你,辛苦把你养大,都不知道你现在在哪里流浪。现在好了,你SSD翅膀硬了,不说一句感谢的话,倒反过来嫌弃我。各位看官,误会了,前面都是演戏,不说你AHCI/SATA不好,怎么能突出我NVMe/PCIe的好,毕竟后者才是男女一号,这么做完全是剧情需要。戏外,SSD不会忘记你AHCI/SATA的好。忘恩负义?蛋蛋不是那种人。

虽然是在戏里,但总说AHCI/SATA的不好,这样真的好吗?蛋蛋是个怀旧的人,突然就有种蛋蛋的忧伤。好吧,以后就谈NVME,不说AHCI了。孰好孰坏,留与读者评说。

戏还得继续演。

每个SQ放入的是命令条目,无论是Admin还是I/O命令,每个命令条目大小都是64字节;每个CQ放入的是命令完成状态信息条目,每个条目大小是16字节。

在继续谈大宝(DB)之前,先对SQ和CQ做个小结:

  1. SQ用以Host发命令,CQ用以SSD回命令完成状态

  2. SQ/CQ可以在Host的内存中,也可以在SSD中,但一般在Host 内存中(所有系列文章都是基于SQ/CQ在Host内存中讲的);

  3. 两种类型的SQ/CQ:Admin和I/O,前者发送Admin命令,后者发送I/O命令;

  4. 系统中只能有一对Admin SQ/CQ,但可以有很多对I/O SQ/CQ;

  5. I/O SQ与CQ可以是一对一的关系,也可以是一对多的关系;

  6. I/O SQ是可以赋予不同优先级的;

  7. I/O SQ/CQ深度可达64K,Admin SQ/CQ深达4K;

  8. I/O SQ/CQ的广度和深度都可以灵活配置;

  9. 每条命令大小是64字节,每条命令完成状态是16字节;

  10. 不要过河拆桥。

SQ/CQ中的”Q”,是Queue,队列的意思,无论SQ还是CQ,都是队列,并且是环形队列。队列有几要素,除了队列深度,队列内容,还有两个重要的,就是队列的头(Head)和尾巴(Tail)。大家都排过队,你加入队伍的时候,都是站到队伍的最后,如果你插队,蛋蛋就会鄙视你。队伍最前头的那个,正在被服务或者等待被服务,一旦完成,就离开队伍。队列的头尾很重要,头决定谁会被马上服务,尾巴决定了新来的人站的位置。DB,就是用来记录了一个SQ或者CQ的Head和Tail。每个SQ或者CQ,都有两个对应的DB: Head DB和Tail DB。DB是在SSD端的寄存器,记录SQ和CQ的头和尾巴的位置。

上面是一个队列的生产/消费模型。生产者往队列的Tail写入东西,消费者往队列的Head取出东西。对一个SQ来说,它的生产者是Host,因为它往SQ的Tail位置写入命令,消费者是SSD,因为它往SQ的Head取出指令执行;对一个CQ来说,刚好相反,生产者是SSD,因为它往CQ的Tail写入命令完成信息,消费者则是Host,它从CQ的Head取出命令完成信息。

举个例子,看图说话.

1. 开始假设SQ1和CQ1是空的,Head = Tail = 0.

2. 这个时候,Host往SQ1中写入了三个命令,SQ1的Tail则变成3。Host在往SQ1写入三个命令后,同时漂洋过海去更新SSD Controller端的SQ1 Tail DB寄存器,值为3。Host更新这个寄存器的同时,也是在告诉SSD Controller:有新命令了,需要你去取。

3. SSD Controller收到通知后,于是派人去SQ1把3个命令都取回来执行。SSD把SQ1的三个命令都消费了,SQ1的Head从而也调整为3,SSD Controller会把这个Head值写入到本地的SQ1 Head DB寄存器。

4. SSD执行完了两个命令,于是往CQ1中写入两个命令完成信息,同时更新CQ1对应的Tail DB 寄存器,值为2。SSD并且发消息给Host:有命令完成,请注意查看。

5. Host收到SSD的短信通知,于是从CQ1中取出那两条完成信息处理。处理完毕,Host又漂洋过海的往CQ1 Head DB寄存器中写入CQ1的head,值为2。

看完这个例子,又重温了一下命令处理流程。之前我们也许只记住了命令处理需要8步(距离曹植一步之遥),看完上面的例子,我们应该对命令处理流程有个更深入具体的认识。

那么,DB在命令处理流程中起了什么作用呢?

首先,如前所示,它记住了SQ和CQ的头和尾。对SQ来说,SSD是消费者,它直接和队列的头打交道,很清楚SQ的头在哪里,所以SQ head DB由SSD自己维护;但它不知道队伍有多长,尾巴在哪,后面还有多少命令等待执行,相反,Host知道,所以SQ Tail DB由Host来更新。SSD结合SQ的头和尾,就知道还有多少命令在SQ中等待执行了。对CQ来说,SSD是生产者,它很清楚CQ的尾巴在哪里,所以CQ Tail DB由自己更新,但是SSD不知道Host处理了多少条命令完成信息,需要Host告知,因此CQ Head DB由Host更新。SSD根据CQ的头和尾,就知道CQ能不能以及能接受多少命令完成信息。

DB的另外一个作用,就是通知作用:Host更新SQ Tail DB的同时,也是在告知SSD有新的命令需要处理;Host更新CQ Head DB的同时,也是在告知SSD,你返回的命令完成状态信息我已经处理,同时表示谢意。

这里有一个对Host不公平的地方,Host对DB只能写,还仅限于写SQ Tail DB和CQ Head DB,不能读取DB。蛋蛋突然想唱首歌:

我俩太不公平爱和恨全由你操纵可今天我已离不开你不管你爱不爱我

Host就是这样痴情。在这个限制下,我们看看Host是怎样维护SQ和CQ的。SQ的尾巴没有问题,Host是生产者,对新命令来说,它清楚自己应该站在队伍哪里。但是Head呢?SSD在取指的时候,是偷偷进行的,Host对此毫不知情。Host发了取指通知后,它并不清楚SSD什么时候去取命令,取了多少命令。怎么破?机智如你,如果是你,你会怎么做?山人自有妙计。给个提示:

这是什么鬼东西?这是SSD往CQ中写入的命令完成状态信息(16字节)。

是的,SSD往CQ中写入命令状态信息的同时,还把SQ Head DB的信息告知了Host!!这样,Host对SQ中Head和Tail的信息都有了,轻松玩转SQ。

CQ呢?Host知道Head,不知道Tail。那怎么能知道Tail呢?思路很简单,既然你SSD知道,那你告诉我呗!SSD怎么告诉Host呢?还是通过SSD返回命令状态信息中。哈哈,看到上图中的“P”吗?干什么用,做标记用。

具体是这样的:一开始CQ中每条命令完成条目中的”P” bit初始化为0,SSD在往CQ中写入命令完成条目时,会把”P”写成1。记住一点,CQ是在Host端的内存中,Host可以检查CQ中的所有内容,当然包括”P”了。Host记住上次的Tail,然后往下一个一个检查”P”,就能得出新的Tail了。就是这样。

最后,给大宝做个小结:

  1. DB在SSD Controller端,是寄存器

  2. DB记录着SQ和CQ的Head和Tail

  3. 每个SQ或者CQ有两个DB: Head DB 和Tail DB

  4. Host只能写DB,不能读DB

  5. Host通过SSD往CQ中写入的命令完成状态获取Head或者Tail

本文转载自SSD技术学习网

Linux阅码场原创精华文章汇总

扫描下方二维码关注"Linux阅码场"

蛋蛋读NVMe之二: 吉祥三宝相关推荐

  1. 房市静心贴:蛋蛋读NVMe之三

    前情提要: 蛋蛋读NVMe之一:为什么刘备需要NVMe 蛋蛋读NVMe之二: 吉祥三宝 有个人一直在思考三个问题:我是谁?我从哪里来?我要去哪里? 你猜这个人最后怎么着? 成了哲学家? 疯了? 疯了的 ...

  2. 蛋蛋读UFS之二:UFS协议栈

    转自:蛋蛋读UFS之二:UFS协议栈 任何一种接口或者协议,都是由一个完整的协议栈组成的.UFS也不例外. UFS定义了一个完整的协议栈.从上到下,依次为应用层.传输层.数据链路层和物理层.UFS使用 ...

  3. nvme命令中prp_蛋蛋读NVMe之三

    有个人一直在思考三个问题:我是谁?我从哪里来?我要去哪里? 你猜这个人最后怎么着? 成了哲学家? 疯了? 疯了的哲学家? 我觉得无外乎这三种结果了. 相比人的世界,这三个问题在NVMe的世界就很容易得 ...

  4. 读论文(二):HMB-SSD: Framework for Efficient Exploiting of the Host Memory Buffer in the NVMe SSD

    读论文(二):HMB-SSD: Framework for Efficient Exploiting of the Host Memory Buffer in the NVMe SSD 问题背景 提出 ...

  5. 蛋蛋读UFS之一:UFS简介

    转载:蛋蛋读UFS之一:UFS简介 我们知道,我们电脑由三大件组成:CPU,内存和硬盘.CPU用以计算和控制,内存用以临时存储程序运行时所需的数据(掉电数据丢失),而硬盘用以长久保存数据(掉电数据不丢 ...

  6. 三宝机器人怎么充电_巨人通力导致吉祥三宝+36号故障怪现象的又一因素

    想必大家都有过这样的经历:在电梯故障频繁出现时,明明可以判断是哪里的问题,但事实却是让你感觉不可思议,并且排查过程颇为周折. 今天和大家分享一下我经历的巨人通力GPS30K电梯出现的吉祥三宝故障的排查 ...

  7. 看看吉祥三宝程序员版本你就明白了

    看看"吉祥三宝"程序员版本你就明白了: // 老大 // 哎 // 咱们今天晚上还加班吗 // 你说呢 // 这次项目能按期完成吗 // 估计够呛 // 那能给咱发奖金吗 // 你 ...

  8. 蛋蛋读UFS之三:UFS数据包UPIU

    转自:蛋蛋读UFS之三:UFS数据包UPIU UFS中流淌的数据包叫做UPIU(UFS Protocol Information Unit,UFS协议信息单元),它是固定格式的数据结构,用以传输应用层 ...

  9. 哥德尔不完全性定理 关系 谓词和代入——哥德尔读后之二十

    哥德尔不完全性定理 关系 谓词和代入--哥德尔读后之二十 这两天从外刊文字中了解到,人工智能AI很牛,不是一般地牛,很可能超越人的智能.但有一个事实,却不是能够轻易就被否定掉的.那就是,所谓现代机器人 ...

最新文章

  1. c语言二叉排序树的创建与查找,C语言实现二叉查找树的插入和删除操作问题求教...
  2. 路由与交换 基础 1:组播
  3. 141 springmvc中 转发 与 重定向
  4. SDM450+android8.1播放左声道音频文件和右声道音频文件,左右喇叭都有声音问题
  5. 多线程:为什么wait()需要放在循环中?
  6. Android手机WIFI与电脑间共享文件
  7. jquery复选框组清空选中的值_jquery操作复选框(checkbox)的12个小技巧总结
  8. 软件工程心理学之9----乙方如何面对甲方2
  9. 我讨厌电脑!一个系统管理员的自白
  10. 预处理,编译,汇编,链接程序的区别
  11. php内li背景色,CSS_css中ul li的背景小图标属性设置的两种情况,这里我们分两种情况列出: ① - phpStudy...
  12. python订餐系统简单版
  13. 机器学习开篇之机器学习的分类
  14. 如何系统学习 Ps、CAD、Office 等软件?
  15. 论文复现_显示屏装配尺寸测量
  16. 生成osm文件_OSM地图本地发布-如何生成各省市矢量地图
  17. Angular属性绑定的功能探索
  18. 输出字符的 ASCII 码
  19. IC618的资源分享及IC618电路显示黄色问题
  20. java语言数学_Java语言实现小学数学练习

热门文章

  1. 关于lib/asm-offsets.c:1:0: error: bad value (armv5) for -march= switch问题解决办法
  2. root用户无法打开xclock_oracle安装过程中图像界面启动问题(xdmcp) | 学步园
  3. 整车电子电气仿真测试解决方案
  4. 澎湃新闻:我在南山写代码,是改变世界还是养家糊口?
  5. 显示计算机101代码,steam错误代码101怎么办_steam错误代码101的解决方法
  6. 02.MySQL索引,以及它们的好处和坏处
  7. AutoJs学习-文字转语音QQ发送
  8. 人脸活体/活性检测方法综述
  9. html,CSS,JavaScript学习笔记
  10. 小米手机一键修改机器码参数