SSD基本的組成結(jié)構(gòu)有Flash顆粒和Flash控制器,F(xiàn)lash控制器有芯片,負(fù)責(zé)Flash的讀寫、磨損均衡、壽命監(jiān)控等。近日,PMC的首席架構(gòu)師張冬在中國(guó)閃存峰會(huì)的分論壇上分享了名為“淺談”閃存控制器架構(gòu)的主題演講。
控制器主要做的就是這么幾件事情:
第一,后端訪問Flash,管理后端Flash顆粒,包括各種參數(shù)控制和數(shù)據(jù)IO??刂破餍枰褟那岸税l(fā)過來(lái)的IO翻譯成Flash的指令格式。其實(shí),不同廠商采用的協(xié)議不一致,后端要做的是適配不同的廠商提供顆粒的參數(shù),雖然大家遵循的協(xié)議一樣,但一些機(jī)密參數(shù)廠商不對(duì)外透露,而有了這些參數(shù)后可以更快更好地在Flash芯片中進(jìn)行讀寫。
第二,前端提供接口和協(xié)議。實(shí)現(xiàn)對(duì)應(yīng)的SAS/SATA target協(xié)議端或者NVMe協(xié)議端,獲取Host發(fā)出的IO指令并解碼和生成內(nèi)部私有數(shù)據(jù)結(jié)果等待執(zhí)行。跟主機(jī)驅(qū)動(dòng),跟上面的協(xié)議棧,利用標(biāo)準(zhǔn)格式輸配到系統(tǒng)里面,接收主機(jī)端發(fā)過來(lái)的指令,這兩個(gè)還不是核心的層次。
第三,最核心的是FTL層。指令接收過來(lái)以后,部件里面怎么處理指令。包括影射,元數(shù)據(jù)、元數(shù)據(jù)保存,磨損均衡等一堆東西都需要處理,所以這塊是各個(gè)廠商競(jìng)爭(zhēng)力的體現(xiàn)。它是最重要的,這塊是第二重要的,這塊反而最不重要,因?yàn)檫@塊是標(biāo)準(zhǔn)化的。
后端都有哪些操作內(nèi)容:

第一,閃存通道控制器,每個(gè)控制器里有多個(gè)通道,每個(gè)通道下有多片F(xiàn)lash,一個(gè)通道掛8片,需要有一個(gè)信號(hào)選擇8片,每次發(fā)一個(gè)信號(hào)下去,要讀哪一片,要告訴他,有一個(gè)片選。通道數(shù)量不同廠商的產(chǎn)品都不一樣,高端的有的16通道、32通道,有的8通道、1通道。它跟后端Flash顆粒有托管協(xié)議。
數(shù)據(jù)寫到Flash的時(shí)候要做兩個(gè)事情:一個(gè)是做ECC校驗(yàn),F(xiàn)lash靠電壓檢測(cè)來(lái)表示。加一個(gè)比較電壓檢測(cè),因?yàn)檫@個(gè)過程容易出錯(cuò),比如說用1.2伏表示零,1.3伏表示1,如果檢測(cè)出來(lái)是1.25伏怎么辦?你是0還是1,因?yàn)槌鲥e(cuò)率非常高,所以需要ECC。
ECC是通用的稱謂,包括好幾種算法,糾錯(cuò)率較低的BCH算法,還有LABC低密度校驗(yàn)法,我們用更少的位校驗(yàn)更多的錯(cuò)誤。高密度是說,我不在乎校驗(yàn)位的容量,最高的就是RAID1,有一份數(shù)據(jù)復(fù)制一份,那個(gè)錯(cuò)了,這個(gè)還在,那個(gè)成本太高了。4K我有多少ECC。LBAC是業(yè)內(nèi)最低密度的校驗(yàn),已經(jīng)達(dá)到理論的極限了。這個(gè)東西做起來(lái)的話,用CPU算的話,這個(gè)速度太慢了。數(shù)據(jù)進(jìn)來(lái)以后,一個(gè)數(shù)據(jù)或者兩個(gè)數(shù)據(jù)輸出。Flash是拿晶體管(音譯),你要往里寫相同數(shù)據(jù)的時(shí)候,我都充電,可能就產(chǎn)生干擾,這時(shí)候出錯(cuò)率就增加了,把原始數(shù)據(jù),可能有多個(gè)零,一萬(wàn)個(gè)零,寫進(jìn)去的時(shí)候,會(huì)用一個(gè)多項(xiàng)式重新算一遍,最后產(chǎn)生的數(shù)據(jù),一個(gè)0,一個(gè)1,這樣就不會(huì)導(dǎo)致相鄰的cell同時(shí)充電,出錯(cuò)率降低,讀出來(lái)的時(shí)候也要經(jīng)過它,把原始數(shù)據(jù)重新算過來(lái),寫到DARM里面,所以需要兩步操作。讀的時(shí)候擾碼,加擾,解擾,看ECC有沒有錯(cuò)誤,有錯(cuò)糾錯(cuò),然后把芯片發(fā)到內(nèi)部,供后續(xù)的程序處理。算RAID的話,多個(gè)顆粒之間做RAID的話用云加速計(jì)算器去算。
前端基本上沒有什么大家都是一樣的,如果你遵從NVMe標(biāo)準(zhǔn)的話,包括提交命令、完成命令這些東西都定好了,這個(gè)數(shù)量可以達(dá)到64K個(gè),同一時(shí)刻,系統(tǒng)里面可能存在64K×64K IO排著,但是系統(tǒng)用不到這么多Queue,因?yàn)榈紫碌慕橘|(zhì)達(dá)不到64K。設(shè)計(jì)的時(shí)候,永遠(yuǎn)不可能達(dá)到,本身就是錯(cuò)誤的,肯定會(huì)達(dá)到,因?yàn)榈讓拥目萍嫉倪M(jìn)步是沒有辦法想象的。
一般來(lái)講,現(xiàn)在的產(chǎn)品,一般做硬件的時(shí)候,比如說做64 Queue,但是這些Queue都是主機(jī)內(nèi)部里的,F(xiàn)lash控制器里面需要對(duì)每個(gè)Queue有一個(gè)對(duì)應(yīng)的接受的窗口,這個(gè)是硬件計(jì)算機(jī),然后會(huì)把地址寫到控制器里面,這時(shí)候控制器知道從主機(jī)內(nèi)存哪個(gè)位置把命令拿過來(lái),控制器是從主機(jī)里面拿命令,不是主機(jī)發(fā)送給控制器。NVMe 1.2的標(biāo)準(zhǔn)里面做了改變,主機(jī)直接把命令扔到控制器少了一步操作。支撐NVMe的控制器不僅僅是軟件的改動(dòng),硬件也需要改動(dòng),你可以拿純軟件模擬,這樣的話就非常慢了,你需要有硬件計(jì)算器在里面。至于指令解碼這塊都是軟件,這塊沒有硬件,這塊做硬解碼不太劃算,基本上拿CPU,把命令接收進(jìn)來(lái),跑代碼算一下。
第三,核心層FTL層:這個(gè)是關(guān)鍵競(jìng)爭(zhēng)力所在,純軟件算法,元數(shù)據(jù)管理,數(shù)據(jù)布局影射、磨損均衡、垃圾回收、緩存策略,發(fā)了IO下來(lái),F(xiàn)lash寫了,你發(fā)一筆下來(lái),我等等,后面可能有一萬(wàn)筆,我把4K放到緩存里面,一萬(wàn)筆就不用下來(lái)了,我就可以降低寫放大。如果一個(gè)顆粒壞了,我也可以算出來(lái)。掉電元數(shù)據(jù)一致性保障,這個(gè)也是體現(xiàn)競(jìng)爭(zhēng)力的地方。之前的產(chǎn)了掉電以后再開機(jī),因?yàn)榭ㄟ€沒有準(zhǔn)備好,一直等卡把元數(shù)據(jù)恢復(fù)出來(lái),重新恢復(fù)一致性才了進(jìn)去。最夸張的可能到八九十都有可能,啟動(dòng)一臺(tái)機(jī)器掉電半小時(shí),現(xiàn)在的新產(chǎn)品,基本上就是10秒,或者幾秒鐘。
這個(gè)算法也不是純軟件的,當(dāng)然也有硬加速的成分在里面,這個(gè)就看你用誰(shuí)家的芯片。有的芯片支持硬加速的東西,比如說鏈表的恢復(fù)。因?yàn)樽隼厥盏臅r(shí)候要用到鏈表,拿傳統(tǒng)的軟件算法,插入一個(gè)鏈表或者追加一些項(xiàng)目的話,耗費(fèi)的周期是非常大的,這個(gè)時(shí)候用硬加速并行起來(lái),再加上一些硬邏輯的加速的話,這塊開銷是可以省下來(lái)了,省下來(lái)以后,IO時(shí)延就降下來(lái)了。Flash時(shí)延很重要,每增加一小步都會(huì)影響時(shí)延,最好是直接到Flash顆粒,什么都不加,但是這樣就沒辦法用,沒有辦法管理Flash了。
以上說的是一款Flash控制器要做的事情。做這些事情有各種各樣的方法,各種各樣的架構(gòu)設(shè)計(jì)。稍微總結(jié)一下。
Flash控制器的兩種策略和方式:
一種是少量的強(qiáng)核心 少量硬件加速。所謂強(qiáng)核心就是一個(gè)核心的性能非常高,頻率也高,里面的器件也多,分支預(yù)判、并行度、數(shù)量、執(zhí)行管道,各種參數(shù)都往上標(biāo),這就所謂的強(qiáng)核心。核心強(qiáng)了以后,硬加速就不需要這么多了,可以用少量的硬加速。
另一種是大量弱核心 大量硬加速。比如說16個(gè)核心,每個(gè)核心比較弱,但是能夠增加執(zhí)行的并行度,我有16個(gè)并發(fā)核心執(zhí)行,我們跑16套處理程序,這是兩種架構(gòu)。
多核心的兩種協(xié)作方式:
多核心的協(xié)作有同構(gòu)協(xié)作和異構(gòu)協(xié)作兩種方式。
同構(gòu)協(xié)作就是每個(gè)核心做的事都是完全一樣的,處理的步驟完全一樣。如果你的控制器陣列里面有16個(gè)IO,有16個(gè)核心,每個(gè)核心都能處理一個(gè)IO,這是同構(gòu)協(xié)作,每筆IO處理的時(shí)候,都有步驟,先指令、解碼,形成對(duì)應(yīng)的操作,下一步算RAID,帶入到表里面,查一下我哪些地方是空的可以寫,再就是找一下影射表之類的,再就是發(fā)送給后端Flash控制器,然后寫下去,一步一步執(zhí)行,每一個(gè)核都可以做這個(gè)事情,這個(gè)是同構(gòu)協(xié)作。
異構(gòu)協(xié)作就是多個(gè)核心做不同的事情。處理同一個(gè)IO,第一個(gè)IO第一步,第一個(gè)核心處理,這個(gè)核心處理完以后,把這個(gè)IO扔到下一個(gè)核心,再處理下一步,我這個(gè)核心空出來(lái)以后,我處理下一個(gè)IO的第一步,這就是所謂的流水線了,異構(gòu)就是這樣的。這叫大量重核心,關(guān)于它的兩種協(xié)作,我之前寫過文章,在公眾號(hào)里面,大家可以看一下。
以PMC產(chǎn)品示例介紹控制器的架構(gòu):
首先它有一個(gè)網(wǎng)絡(luò),網(wǎng)絡(luò)承載16個(gè)CPU核心,每個(gè)核心里面有一個(gè)類似于網(wǎng)卡的控制器,網(wǎng)卡連到網(wǎng)絡(luò)上,說白了網(wǎng)絡(luò)就是4口路由器或者交換機(jī)連起來(lái)的網(wǎng)絡(luò),多個(gè)CPU之間連起來(lái),此外還有硬加速模塊。
這里有以下幾部分:
RAM控制器,因?yàn)樾酒闲枰幸欢康腞AM放臨時(shí)數(shù)據(jù),寫放大,讀出來(lái)寫進(jìn)去,都要走RAM,
然后是PCIe控制器,這個(gè)跟前端PCIe對(duì)等的控制器,從這兒接收過來(lái)VM1。
后端Flash控制器,連Flash顆粒,通過一定數(shù)量的通道。
再就是加速器:
包括緩沖加速器,這個(gè)就是分8份,因?yàn)槊孔鲆粋€(gè)操作,都需要有相應(yīng)的內(nèi)存,把數(shù)據(jù)拷到內(nèi)存里面,內(nèi)存的維護(hù)很費(fèi)時(shí)費(fèi)力。比如說之前在X86裝Linux,有很多的計(jì)算量。對(duì)于閃存,精打細(xì)算,必須把性能做到極致,這塊用硬加速;
鏈表加速器,剛才已經(jīng)提到了,哪塊空著,哪塊被應(yīng)用,這塊用軟件維護(hù)很費(fèi)力,(所以需要在這里作加速);
XOR加速器,XOR要用硬加速,當(dāng)然還有外圍輔助,串口等各種其他的控制器,圖中沒有具體顯示。
所有模塊通過一個(gè)網(wǎng)絡(luò)互傳數(shù)據(jù),達(dá)到高度并行的目的,所以這個(gè)網(wǎng)絡(luò)速度非???。
軟件的并行度。16個(gè)核心,我們提供的參考的部件,SSD廠商把自己優(yōu)化的東西放進(jìn)去開發(fā)出自己的部件,這幾種基本上包含這樣一些程序:因?yàn)槊總€(gè)IO讀的地址可能有重疊,所欲需要有一個(gè)鎖定協(xié)調(diào);有管命令解析的,有管啟動(dòng)的,最核心是:有管日志的,有管磨損均衡的,有管查表的,有關(guān)寫數(shù)據(jù)的,還有引擎對(duì)應(yīng)的舉動(dòng)都在這兒,管前端的PCIe 管理員,初始化的配置,需要由它處理,data manager,這是主程序,分析干什么,生成一堆的后續(xù)步驟下發(fā)下去。其實(shí)每一塊都可以跑在一個(gè)核心上,同一個(gè)角色可以復(fù)制多份,充分變小。16個(gè)核心,達(dá)到16份程序并行的運(yùn)行,16個(gè)流水線的Stage,這樣就可以屏蔽處理過程中的時(shí)延。









