一、故事开篇
最近有同学在咨询,SATA SSD是否需要NCQ功能?借此机会,今天我们来聊聊这个比较古老的话题,关于SATA协议的NCQ的故事。
首先我们先回顾下SATA与NCQ的历史:
2003年,SATA协议1.0问世,传输速率150MB/s, 主要是为了取代PATA(最大133MB/s), 这个时候还没NCQ。
SATA1.0问世1年后,2004由于更好性能的诉求,SATA 2.0问世,传输速率300MB/s,这个时候NCQ就诞生了。之后分别在2005年、2007年做了两次的升级迭代SATA 2.5和SATA 2.6。
2009年,SATA 3.0出现,之后迭代了五次,分别是2011年SATA 3.1,2013年SATA 3.2,2016年SATA 3.3,2018年SATA 3.4,2020年SATA 3.5。自此SATA协议就没有更新了,大家都去拥抱NVMe了。
其次,我们需要先了解下NCQ是什么?我们这里主要解析一下SATA NCQ(Native Command Queuing)原生指令序列的相关内容。
二、SATA NCQ 原生指令序列
NCQ是SATA中的命令协议,允许同时在Drive中执行多个命令。当用户的应用程序发送多条指令到用户的硬盘,NCQ可以优化完成这些指令的顺序,从而降低负荷达到提升性能的目的。
此外,SATA Spec中还定义了三个特殊的功能来加强NCQ的性能:
Race-Free Status Return: 无竞争状态返回机制,允许任何指令任何时间报告执行状态,此外,多个命令执行完毕信息可以打包一起回传。
Interrupt Aggregation: 在DMA传输模式下,硬盘通知传输结束,会引起一个中断(Interrupt),造成延迟。所以,SATA spec提供中断聚集机制。如果硬盘同时间内完成多组命令,这些命令完成所引起的中断就可以聚集在一起,大幅减少中断的数目,这对于降低中断延迟有极大的贡献。
First-Party DMA(FPDMA): SATA允许硬盘端通过DMA setup FIS直接对Host控制器送出数据传输请求,DMA引擎就可以直接进行资料传输,这个过程中并不需要Host端软件的介入。
当Drive收到一个Command,是要将其重新排列?还是立即执行呢?这怎么区分呢?
不怕,SATA Spec定义了两个特殊的NCQ指令:
Read FPDMA Queued;
Write FPDMA Queued;
从上面Read FPMA Queued Inputs和Write FPMA Queued Inputs我们可以看到红色框里面有一个特别的5-bit参数TAG(bit3~bit7). 这个参数就代表了NCQ一次可以最多执行32个Commands(如下图红色框Command List)。
在Device端,当Queued Commands(最多32)中的一个write或者read准备好传输数据时,通过发送DMA setup FIS告知Host已准备好数据传输,其中要附带更新Tag Value(如下图红色框)。
在Device端,当Queued Commands执行完成后, 通过发送Set Device Bits FIS告知Host完成状态,此时SActive区域对应TAG的相关内容(最多32个Command)。
FPDMA Read Command(60h) Protocol如下:
我们抓取了一个FPDMA Read Command(60h)的SATA trace,如下图:
从上面的SATA trace我们可以得到:
这个FPDMA read cmd对应的Tag=8;
这个FPDMA read cmd要读取32768 bytes的数据; Data FIS中的数据长度最大为2048 DWs,也就是8192 Bytes。所以,我们可以看到在上面的sata trace中,分4次发送Data FIS来实现32768 bytes数据的传输。
FPDMA Write Command(61h) Protocol如下:
我们抓取了一个FPDMA Write Command(61h)的SATA trace,如下图:
从上面的SATA trace我们可以得到:
这个FPDMA write cmd对应的Tag=0xEh=14;
这个FPDMA write cmd要写入131072 bytes的数据;Data FIS中的数据长度最大为2048 DWs,也就是8192 Bytes。所以,我们可以看到在上面的sata trace中,分16次发送Data FIS。但是每发送一个DMA DATA FIS后,要再次收到DMA Activate FIS才能发送下一个DMA DATA FIS;
下面我们再看个完整的例子加深一下对NCQ的理解:
举例:Host向Device发送两个Read FPDMA Queued指令
针对这个例子,我们作两个假设:
假设1:
第一个Read FPDMA Queued指令 Tag=0;
第二个Read FPDMA Queued指令 Tag=5;
假设2:
Device要先执行第二个指令(Tag=5), 然后在执行第一个指令(Tag=0)
上图中指令下发流程如下:
Host先下发第一个Read FPDMA Queued指令,并且SActive bit0=1, 写入NCQ buffer,这时NCQ队列深度=1;
Host先下发第二个Read FPDMA Queued指令,并且SActive bit0 & bit5=1, 写入NCQ buffer,这时NCQ队列深度=2;
在假设2中,我们要求先执行第二个指令(Tag=5),那么,这个时候就需要NCQ对这两个指令重新排序,如下图红色框显示:
NCQ对这个两个指令重新排序后,就开始执行依次这两个Read FPDMA Queued指令, 指令执行流程见前面介绍的“FPDMA Read Command(60h) Protocol”内容。
上图是执行Tag=5指令的示意图,下图为执行Tag=0指令的示意图:
三、对NCQ的误解
NCQ是最开始诞生的背景,是为了优化机械硬盘性能,通过NCQ优化命令的排序,减少磁头的移动,以达到提升性能的目的。
此外,网上有一些SATA SSD开启NCQ后出现异常的案例,关闭NCQ恢复正常(其实,这里出现异常,并不是NCQ本身的问题,而是NCQ打开后的压力让部分硬盘型号出现不兼容或者IO处理不及时的问题)。比如如下信息:
结合上面两点,有很多人对NCQ产生了误解:NCQ是提升HDD性能的,对SATA SSD没有用,且不能开启。
小编想说的是:NCQ在整个计算机IO栈中,类似于水闸一样,开启NCQ(一次发送32个命令),关闭NCQ(每次只发送1个命令)。SSD虽然没有机械臂和磁头,但是SSD是多通道的,开启NCQ后,硬盘控制器可以根据数据请求和数据存储区域NAND的分布,利用多通道并发的优势,提升性能。
比如,Intel发布的官方技术文档中也强调这一点,NCQ可以同样提升SSD性能。
此外,再分享一个业内其他同学测试的数据,NCQ开启后,随着QD的增加,性能也在不断提升。
目前SATA SSD原生就是支持NCQ的,比如随机选取的Intel、Samsung、Micron、WD、Realtek等厂商的几款对NCQ支持情况。
在Linux内核的定义中,Queue Depth=1是关闭NCQ,其他是开启NCQ
因此,在linux中开启NCQ的方式也比较简单:
开启NCQ:echo 31 > /sys/block/<device>/device/queue_depth
关闭NCQ:echo 1 > /sys/block/<device>/device/queue_depth
四、话题讨论
讲述到这里,你觉得SATA SSD是否需要开启NCQ呢?给出你的观点哦~
如果你有不同的想法与思路,欢迎留言交流,非常感谢!
精彩推荐:
全景解析SSD IO QoS性能优化
NVMe IO数据传输如何选择PRP or SGL?
存储随笔2022年度最受欢迎文章榜单TOP15
从主流企业级PCIe Gen4 SSD性能对比,畅谈SSD性能调优的思考
浅析nvme原子写的应用场景
YMTC X3 NAND 232L 终露真容,全球领先
芯片级解密YMTC NAND Xtacking 3.0技术
Backblaze 2022 Q3 硬盘故障质量报告解读
漫谈云数据中心的前世今生
多维度深入剖析QLC SSD硬件延迟的来源
漫谈固态硬盘SSD全生命周期的质量管理
汽车存储SSD面临的挑战与机遇
超大规模云数据中心对存储的诉求有哪些?
SSD写放大的优化策略要统一标准了吗?
“后Optane时代”的替代存储方案有哪些?
浅析PCIe链路LTSSM状态机
浅析Relaxed Ordering对PCIe系统稳定性的影响
实战篇|浅析MPS对PCIe系统稳定性的影响
浅析PCI配置空间
浅析PCIe系统性能
PLC SSD虽来但远,QLC SSD火力全开
最全电脑固态硬盘SSD入门级白皮书
存储随笔《NVMe专题》大合集及PDF版正式发布!
加权循环仲裁WRR特性对NVME SSD性能有什么影响?
Linux NVMe Driver学习笔记之9: nvme_reset_work压轴大戏