从今天开始,老男孩要开始讲PCIe了。对我来说,这是个很大的挑战:首先,我自己本身,对PCIe并没有做到胸有成竹,我的PCIe知识也只是停留在理论阶段,我并没有实际做过任何有关PCIe的东西;其次,我要把PCIe讲得深入浅出,让读者轻易接受,我觉得很难,根本原因就是我还没有做到胸有PCIe;最后,我的文章都会通过ssdfans公众号推出(还没有关注的同学,赶快关注),很多读者都是PCIe高手,班门弄斧,我深感压力。但尽管如此,我还是决定出发,我自己努力学习,尽我最大能力把我学到的东西分享给大家,也希望各位PCIe大拿们,帮忙斧正文章的错误,我希望不是我一个人,而是和各位大拿们一起,带领大家攀上PCIe的高峰。
我是从事SSD工作的,为什么要讲PCIe,原因很简单,现在很多SSD都开始使用PCIe接口。那为什么SSD要用PCIe接口?因为它快,比SATA快。它究竟有多快?我们今天首先从PCIe接口的速度开始我们的PCIe之旅。
PCIe发展到现在,从PCIe 1.0,PCIe 2.0,到现在的PCIe 3.0,速度一代比一代快。
Link Width这一行,我们看到X1,X2,X4…,这是什么意思?这是指PCIe连接的通道数(Lane)。就像高速一样,有单根道,有2根道的,有4根道的,不过像8根道或者更多道的公路不常见,但PCIe是可以最多32条道的。
两个设备之间的PCIe连接,叫做一个Link,如下图所示:
从A到B,之间是个双向连接,车可以从A驶向B,同时,车也可以从B驶向A,各行其道。两个PCIe设备之间,有专门的发送和接收通道,数据可以同时往两个方向传输,PCIe spec称这种工作模式为双单工模式(dual-simplex),可以理解为全双工模式。
SATA是什么工作模式呢?
和PCIe一样,SATA也有独立的发送和接收通道,但与PCIe工作模式不一样:同一时间,只有一条道可以进行数据传输,也就是说,你在一条道上发送数据,另外一条道上不能接收数据,反之亦然。这种工作模式应该是半双工模式。PCIe犹如我们的手机,双方可以同时讲话,而SATA就是对讲机了,一个人在说话,另外一个人就只能听不能说。
回到前面PCIe带宽那张表,上面的带宽,比如PCIe3.0x1,带宽为2GB/s,是指双向带宽,即读写带宽。如果单指读或者写,该值应该减半,即1GB/s的读速度或者写速度。
我们来看看表里面的带宽是怎么算出来的。
PCIe是串行总线,PCIe1.0的线上比特传输速率为2.5Gb/s,物理层使用8/10编码,即8比特的数据,实际在物理线路上是需要传输10比特的,因此:
PCIe1.0 x 1的带宽=(2.5Gb/s x 2(双向通道))/ 10bit = 0.5GB/s
这是单条Lane的带宽,有几条Lane,那么整个带宽就0.5GB/s乘以Lane的数目。
PCIe2.0的线上比特传输速率在PCIe1.0的基础上翻了一倍,为5Gb/s,物理层同样使用8/10编码,所以:
PCIe2.0 x 1的带宽=(5Gb/s x 2(双向通道))/ 10bit = 1GB/s
同样,有多少条Lane,带宽就是1GB/s乘以Lane的数目。
PCIe3.0的线上比特传输速率没有在PCIe2.0的基础上翻倍,不是10Gb/s,而是8Gb/s,但物理层使用的是128/130编码进行数据传输,所以:
PCIe3.0 x 1的带宽=(8Gb/s x 2(双向通道))/ 8bit = 2GB/s
同样,有多少条Lane,带宽就是2GB/s乘以Lane的数目。
由于采用了128/130编码,128比特的数据,只额外增加了2bit的开销,有效数据传输比率增大,虽然线上比特传输率没有翻倍,但有效数据带宽还是在PCIe2.0的基础上做到翻倍。
这里值得一提的是,上面算出的数据带宽已经考虑到8/10或者128/130编码,因此,大家在算带宽的时候,没有必要再考虑线上编码的问题了。
和SATA单通道不同,PCIe连接可以通过增加通道数扩展带宽,弹性十足。通道数越多,速度越快。不过,通道数越多,成本越高,占用更多空间,还有就是更耗电。因此,使用多少通道,应该在性能和其他因素之间进行一个综合考虑。单考虑性能的话,PCIe最高带宽可达64GB/s,PCIe 3.0 x 32对应的带宽,很恐怖的一个数据。不过,现有的PCIe接口SSD,一般最多使用4通道,如PCIe3.0x4,双向带宽为8GB/s,读或者写带宽为4GB/s。
几个GB/s的传输速度,读写小电影那是杠杠的。
在此,顺便来算算PCIe3.0x4理论上最大的4K IOPS。PCIe3.0x4理论最大读或者写的速度为4GB/s,不考虑协议开销,每秒可以传输4GB/4K个4K大小的IO,该值为1M,即理论上最大IOPS为1000K。因此,一个SSD,不管你底层用什么介质,flash还是3d xpoint,接口速度就这么块,最大IOPS是不可能超过这个值的。
PCIe是从PCI发展过来的,PCIe的”e”是express的简称,快的意思。PCIe怎么就能比PCI(或者PCI-X)快呢?PCIe在物理传输上,跟PCI有着本质的区别:PCI使用并口传输数据,而PCIe使用的是串口传输。我PCI并行总线,单个时钟周期可以传输32bit或者64bit,怎么就比不了你单个时钟周期传输1个bit数据的串行总线呢?
在实际时钟频率比较低的情况下,并口因为可以同时传输若干比特,速率确实比串口快。随着技术的发展,数据传输速率要求越来越快,要求时钟频率也越来越快,但是,并行总线时钟频率不是想快就能快的。
在发送端,数据在某个时钟沿传出去(左边时钟第一个上升沿),在接收端,数据在下个时钟沿(右边时钟第二个上升沿)接收。因此,要在接收端能正确采集到数据,要求时钟的周期必须大于数据传输的时间(从发送端到接收端,flight time)。受限于数据传输时间(该时间还随着数据线长度的增加而增加),因此时钟频率不能做得太高。另外,时钟信号在线上传输的时候,也会存在相位偏移(clock skew ),影响接收端的数据采集;还有,并行传输,接收端必须等最慢的那个bit数据到了以后,才能锁住整个数据 (signal skew)。
PCIe使用串行总线进行数据传输就没有这些问题。它没有外部时钟信号,它的时钟信息通过8/10编码或者128/130编码嵌入在数据流,接收端可以从数据流里面恢复时钟信息,因此,它不受数据在线上传输时间的限制,你导线多长都没有问题,你数据传输频率多快也没有问题;没有外部时钟信号,自然就没有所谓的clock skew问题;由于是串行传输,只有一个bit传输,所以不存在signal skew问题。但是,如果使用多条lane传输数据(串行中又有并行,哈哈),这个问题又回来了,因为接收端同样要等最慢的那个lane上的数据到达才能处理整个数据。