基于FPGA的双盘NVMe SSD的RAID0模式读写实现及测试

4 篇文章 1 订阅

项目背景

  课题组使用FPGA实现了NVMe SSD高速读写,在前文中介绍了系统的架构以及不同硬盘在高速存储系统下的读写测试。建议阅读下文前,熟悉一下前两篇文章:FPGA实现高带宽NVMe SSD读写你所不知道的NVMe SSD固态硬盘读写速度及国货的惊喜–基于FPGA的速度测试

  前文中实现NVMe持续写入带宽为2.3GB/s,因项目数据带宽远大于2.3GB/s,因此还需对系统进行改进,以增加存储带宽。

  本文将介绍双盘NVMe SSD RAID0读写的实现以及性能测试。

RAID模式

  RAID(Redundant Array of Independent Disks),即独立磁盘冗余阵列。其实就是用多个独立的磁盘组成在一起形成一个大的磁盘系统,从而实现比单块磁盘更好的存储性能和更高的可靠性。

  RAID的等级分为标准RAID等级和混合RAID等级。标准RAID等级是最基本的RAID配置集合,单独或综合利用数据条带、镜像和数据校验技术。常用的标准RAID等级有RAID0、RAID1、RAID5和RAID6。

  RAID0代表了所有RAID级别中最高的存储性能。RAID1与RAID0刚好相反,是为了增强数据安全性使两块磁盘数据呈现完全的镜像。RAID5是RAID0和RAID1的折中方案。RAID5具有和RAID0相近似的数据读取速度,只是多了一个奇偶校验信息。RAID6与RAID5相比,前者增加第二个独立的奇偶校验信息块。

  系统对性能的要求比较严格,目的就是提高存储带宽。所以基于实际项目的需求,以及实现的成本和设计的难易度,我们选用RAID0作为双盘读写的技术方案。使用RAID0模式实现本项目中的高速数据吞吐。RAID0是将两块以上的磁盘并联在一起,形成大容量的存储。由于可以并发执行I/O操作,总线带宽可以得到充分的利用,所以RAID0的速度是所有级别中最快的。理论上讲,一个由N块磁盘组成的RAID0,它的读写性能是单个磁盘性能的N倍,但由于总线带宽等多种因素的限制,实际的性能提升低于理论值。RAID0的缺点则是安全性较差,一旦数据损坏,将无法恢复。

在这里插入图片描述
  在RAID0的实现上,需要解决的便是并发执行I/O操作,如何让数据并行地读写两个SSD,是提升读写性能和存储带宽的关键,同样还要保证每个SSD读写数据的准确性。

实现架构设计

  理论上,现有的NVMe协议给硬盘的并行读写留下的控制空间不多。在协议栈层面,NVMe的IO操作碎片化。一个大的数据读写任务会被分解为若干个子任务,每个读写的一个子任务都是单独发送。Host端的NVMe协议执行过程中将子任务放入队列中通知硬盘来取命令,硬盘最终完成命令后,通知Host任务完成,循环工作直至所有任务完成。详细过程可以参考NVMe spec。

独立RC主控,独立控制器架构

  最理想的RAID0的实现架构是两个独立线程同时驱动独立的NVMe Host以实现两个完全独立的协议解析及读写操作过程,这样基本能实现几乎完美的双倍速。其实现框图如图所示:
在这里插入图片描述
  本系统使用的是Xilinx Zynq的XCZU7EG系列芯片。该系列芯片的PS部分有四个ARM Cortex-A53的CPU内核,最高主频可达1.5GHz。理论上,该芯片应该可以实现两个独立协议解析及读写操作的过程。

  Xilinx Zynq UltraScale+ 芯片的结构框图如下所示:
在这里插入图片描述
  图中,红框圈部分为Zynq的多核结构,即4个Arm Cortex A53。对于四核结构而言, 以其1GHz以上的主频,其计算能力应该是比较强的。从运算能力的角度,该4核CPU足够满足双盘RAID0模式的运算需求。但是在多数嵌入Zynq的系统中,ARM处理器一般是用作控制及系统调度的功能,需要处理器通过各种端口对外发送数据及控制指令。这意味着,运算能力不是衡量该处理器是否可以胜任该任务的唯一考量因素。除了运算能力,端口的数据吞吐能力,也是影响该双盘RAID0模式控制任务的重要考量指标。即使内部的算力再强,多核在和外界交互的时候,速度能否会提上去,读写时能否会达到很高的带宽是需要认真考虑的。

  我们尝试通过双核做简单的hello world和流水灯实验,但是实际的效果不尽人意,即使对于这么简单的任务,使用双核执行,输出窗口的反应速度很慢。当然由于时间的原因及有限的多核操作的资料,我们不保证所做的测试实验是完全正确的。(欢迎对此部分熟悉的朋友和我们交流。)根据现有的情况,预估进行RAID0这样工程量相对比较大的任务时,速度会慢得更多,不符合我们高速存储的要求。

独立RC主控,共享控制器架构

  由于Zynq的多核处理器无法实现两个独立的NVMe协议解析及读写操作过程,因此考虑使用逻辑模块和处理器混合的模式,实现单处理器控制两个独立RC host的功能。

  该架构一方面在PL中使用两个独立的逻辑模块实现了NVMe协议解析的高速部分,另外一方面,使用PS中的ARM处理器完成对时间要求不高的一些控制功能,简化逻辑模块的设计及实现工作,充分利用芯片中的现有资源以达到快速系统构建并满足高速数据读写的要求。本质上,两个独立的逻辑模块相当于第一种架构中两个独立的NVMe控制器,只是将两个原来独立进程中的一部分非时间限制的工作合并后,放到一个处理器中统一实现。实现框图如下图所示:
在这里插入图片描述
  通过单核的处理器实现对两个RC host的控制,并且每个RC host分别与对应的EP(End Point)进行交互。这种方式可以让两个EP分别隶属于两个不同RC,即两个不同的PCI域内,互不干扰,对EP(NVMe SSD)的读写控制实现比较简单,且没有寻址,冲突的风险,具有较好的安全性。

共享RC主控及控制器架构

  在Xilinx Zynq UltraScale+ FPGA中,其提供的PCIe3.0 PHY为16x(16 lane),而一个NVMe SSD只是用到了其中的4 lane,即4x。而剩余的12对高速端口是无法再被其他模块或是系统调用的,这意味着,器件中的PCIE端口的3/4的资源没有被有效的使用。因此,理想的高效系统是使用一个RC连接两个EP,从而实现双盘读写。实现框图如图所示:
在这里插入图片描述
  在市面上可以看到某些高端的NVMe SSD扩展卡就是基于此原理进行设计的。以华硕的HYPER M.2 X16 V2扩展卡为例,该扩展卡采用PCIe 3.0 x16接口,可安装4个M.2 PCIe 3.0 x4 NVMe SSD,其官方标称最高可突破12GB/s读取速度。

  所以该架构实现的关键是一条原本一体化的PCIe x16总线可否拆分为4个独立的x4通道使用。从基本原理上来说,一定可以的。但是在实际实现中,除了大厂有能力从底层构建模块外,我们多数人都需要调用一些由厂家提供的基本模块。Xilinx的FPGA器件中,很难直接调用其内嵌的PCIe 3.0 x16 PHY。所以该方案的实现基本取决于Xilinx所提供的,含有PCIe 3.0 x16 PHY的模块中,是否提供了将总线拆分的功能。否则,即使就是差了一点点,但也是隔岸相望,无能为力。我想,行业内的同业朋友也有和我们一样的无奈吧,受制于人,只能仰人鼻息。所以支持国产,支持自主知识产权。限于时间和精力,该方案是否可行我们没有进一步的详细研究,待以后有时间的吧。

  综合以上的情况考虑,最后决定选用比较稳妥的架构,即独立RC主控,共享控制器架构的RAID0实现架构。这一架构实现成功后,我们会尝试其它的架构方案的实现。

架构实现

  基于Xilinx Zynq 的XCZU7EG系列芯片实现独立RC主控,共享控制器架构,采用软硬协同,基于PCIe 3.0实现NVMe协议。

  系统使用主芯片XCZU7EG内部集成的PCIe x16 PHY 及RC硬核,完成PCIe协议层。因为是独立RC主控,所以使用两组PCIe IP,实现两个独立的RC host。NVMe协议解析的任务由PS端ARM处理器及两个各自独立的逻辑控制模块实现,完成PCIe和NVMe Host功能。

  系统使用由处理器产生的伪数据,放入PS的DDR中,由ARM裸机启动系统及部分NVMe协议初始化,PL和PS端协同完成PCIe及NVMe协议。

在这里插入图片描述
  系统通过Cortex A53对NVMe设备初始化,协议中对时间及时延要求较高的任务分配及更新Doorbell、读写命令发送和完成响应均由逻辑模块实现以保证系统的实时响应及高速数据的读写。前端数据存储于DDR,通过AXI总线,划分为两路发送至各路PCIe总线并路由至对应的SSD,构成RAID0结构。

  在NVMe协议的实现上,为了尽量做到并行执行,在子任务的调度上,对原本的协议做了灵活性的实现,按照标准的协议规范,在子任务发送和响应方面做了优化。

  双盘读写存储的功能,经数据校验,准确的实现双盘RAID0的功能,接下来需要大于读写性能进行进一步的测试。

测试验证

  测试平台使用的是基于XCZU7EG的核心板和含双M.2接口的底板组合而成的系统。待测NVMe SSD选用的是两块三星980 500GB SSD和两款忆芯科技SSD。两块三星980 500GB SSD组成为一组双盘组合,两块忆芯科技SSD组成另一组双盘组合。测试中,一次向双盘读写总量为1GB的裸数据,不带任何文件系统,并得到总平均速度并将之与单盘的速度进行对比得到速度提升的倍率。
在这里插入图片描述
在这里插入图片描述

准确性测试

  给双盘读写1GB的数据,随后按照写入的顺序读取这些数据,并和写入的数据作对比。可以看到每个SSD读出的数据皆与写入的数据一致,证明顺序读写的功能是正常执行的,数据上没有出现错误。实际测试界面如下图所示。
在这里插入图片描述

数据写入测试

  我们分别使用三星980单盘在该系统上测试得到单盘写入速度约为2.3GB/s,读出速度为2.8GB/s。使用忆芯单盘在该系统上测试得到单盘写入速度约为2.2GB/s,读出速度为2.7GB/s。

  三星980双盘RAID0的测试界面如下图一所示,忆芯双盘RAID0的测试界面如下图二所示。

  三星双盘测试结果显示,写入速度为4.2GB/s,约为单盘的1.8倍。此次忆芯双盘测试结果显示,写入速度为4.3GB/s,约为单盘的1.9倍。得到这样的结果让我们很吃惊,也很意外,忆芯双盘的写入速度已经很贴近RAID0的理论写入速度,应该是快达到了性能的极限了。
图一:三星980双盘RAID0的测试界面

图一  三星980双盘RAID0的测试界面

图二:忆芯双盘RAID0的测试界面

图二  忆芯双盘RAID0的测试界面

数据读出测试

  两个三星980组成的双盘组合,读出速度为4GB/s,约为单盘的1.4倍。两款忆芯SSD组成的双盘组合,读出速度为4.2GB/s,约为单盘的1.5倍。读出速度确实有一定的提升,但距离理想的2倍速度还是有些差距。

  通过这次双盘读写测试,我们看到,两款SSD读出速度的倍率都低于写入速度的倍率。理论上,因为读出速度快于写入速度,所以因为双盘调度所引起的额外时间消耗所引起的速度跌落在数值上肯定要多些。但是目前实测的这个结果与预期不太相符,预期读出速度的倍率和写入速度的倍率可能略差一点,但不应该这么多。这个问题我们还在解决中,如果各位读者有任何见解和想法,欢迎大家一起讨论。

个人的一点感受(兼回答网友的一些问题)

  用FPGA的方式实现了NVMe的读写控制,有不少朋友私信问我是否容易,多久能做出来。就我的经历,时间其实不是很长,但这其中遇到的问题确实不少。技术上,协议是公开的,只要按照协议的规范做就一定能成功。所以,从这个层面上来说,这个实现不复杂。

  客观的说,到现在,我们也不敢说将PCIe及NVMe的协议完全读懂了。所以从这个层面上说,这个实现也不容易。在这个实现过程中,最大的难题就是解决各种各样的问题、故障。就因为目前我们还做不到将协议理解得彻彻底底,所以面对问题,其实做不到手拿把掐地找到解决办法。引起问题(故障)的原因往往有很多。我们基本上是根据对协议的理解,像盲人摸象一样一步步的去试,从我们觉得可能性最大的地方开始。我们的运气不错,也可能是我们对协议的理解到了一定程度,每次在解决问题的时候,基本熬过一段时间就都能找到问题的所在,然后一直下去,最后做出整个系统。算是一半技术,一半运气吧。技术的东西,要难也很难,卡死了,就是走不下去。说容易也容易,就是张“窗户纸”,一捅就破了。在这里,祝各位技术同仁在熟悉协议的基础上,拥有好运气吧!

声明

本文的内容是学校实验室项目中系列工作的一部分。后续还将推出基于NVMe的RAID0的实现的优化及更多实现方案的论。为了方便成为一个系列,就是用最初的这个账号发文,请大家知晓。
如果需要讨论,联系方式如下:
北京市可线下,地址:北京市海淀区中关村南大街5号北京理工大学。
非京可联系:Tel:13810602873(微信同号)
E-mail:liuzhenyu@bit.edu.cn

  • 20
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值