錢 璐 李 弋 吳毅堅(jiān) 趙文耘
(復(fù)旦大學(xué)軟件學(xué)院 上海 201203) (上海市數(shù)據(jù)科學(xué)重點(diǎn)實(shí)驗(yàn)室(復(fù)旦大學(xué)) 上海 200433)
非易失性內(nèi)存設(shè)備NVM(Non-volatile memory)是指在系統(tǒng)掉電時(shí)仍能保持?jǐn)?shù)據(jù)不丟失的存儲(chǔ)設(shè)備。從發(fā)展歷程看,主要分為塊尋址和字節(jié)尋址兩種。塊尋址設(shè)備性能比動(dòng)態(tài)隨機(jī)存儲(chǔ)器DRAM(Dynamic Random Access Memory)低得多,而字節(jié)尋址設(shè)備性能接近DRAM。針對(duì)NVM建立訪問(wèn)模式的研究主要集中在兩個(gè)方面。一方面將NVM當(dāng)作存儲(chǔ)設(shè)備,在NVM上建立文件系統(tǒng)進(jìn)行持久內(nèi)存管理[1]。另一方面,對(duì)于按字節(jié)尋址的NVM,將其替代傳統(tǒng)DRAM,提供應(yīng)用程序load/store訪問(wèn)方式[2]。前者并沒(méi)充分挖掘NVM優(yōu)秀特性,沒(méi)有最大限度降低軟件系統(tǒng)開(kāi)銷。后者直接訪問(wèn)NVM,繞過(guò)很多軟件層包括系統(tǒng)調(diào)用、文件系統(tǒng)等,大大降低了訪問(wèn)延遲。本文設(shè)計(jì)的非易失性內(nèi)存卷模式通過(guò)將多塊不同種類NVM組織成地址連續(xù)的持久內(nèi)存卷,簡(jiǎn)稱PM卷(Persistent Memory Volume),并將卷映射到用戶空間。既提供處理器load/store訪問(wèn)方式,也對(duì)異構(gòu)NVM設(shè)備實(shí)現(xiàn)有效管理。
主要從為NVM設(shè)備建立文件系統(tǒng)、以load/store方式直接訪問(wèn)NVM設(shè)備、內(nèi)存通道劃分、熱數(shù)據(jù)劃分四方面闡述相關(guān)工作。
BPFS[3]文件系統(tǒng)以字節(jié)尋址方式管理NVM,通過(guò)在文件系統(tǒng)構(gòu)建樹(shù)狀數(shù)據(jù)結(jié)構(gòu),省去文件系統(tǒng)緩存與映像間的數(shù)據(jù)拷貝,從而減少對(duì)NVM的寫(xiě)入。SCMFS文件系統(tǒng)[4]與BPFS一樣在持久性內(nèi)存中不需要數(shù)據(jù)拷貝,并且盡可能為每一個(gè)文件分配連續(xù)空間從而提供優(yōu)越的性能。PMFS文件系統(tǒng)[5]繞開(kāi)了文件系統(tǒng)緩存直接訪問(wèn)NVM,避免了系統(tǒng)中數(shù)據(jù)的拷貝。NOVA[6]文件系統(tǒng)通過(guò)為每個(gè)文件inode維持一個(gè)日志來(lái)提高系統(tǒng)并發(fā)性,并在日志之外存儲(chǔ)文件數(shù)據(jù)來(lái)減少垃圾回收的開(kāi)銷,最終在混合NVM內(nèi)存結(jié)構(gòu)中最大化性能。
在NVM單層存儲(chǔ)模型中,內(nèi)存中可以存儲(chǔ)持久化數(shù)據(jù)結(jié)構(gòu),所以Haris Volos等[7]提出Mnemosyne,Joel Coburn等[8]提出NV-Heaps,提供了新的NVM編程接口。Mnemosyne和NV-Heaps通過(guò)提供用戶態(tài)的編程接口,使應(yīng)用程序能夠在用戶態(tài)訪問(wèn)非易失內(nèi)存設(shè)備,避免了通過(guò)文件系統(tǒng)訪問(wèn)NVM的系統(tǒng)開(kāi)銷,包括系統(tǒng)調(diào)用、文件系統(tǒng)接口、設(shè)備驅(qū)動(dòng)程序等。
Muralidhara等[9]提出一種應(yīng)用感知的內(nèi)存通道隔離方法來(lái)減少多核環(huán)境下的訪存干擾,該方法映射相互之間可能產(chǎn)生嚴(yán)重訪存沖突的應(yīng)用的數(shù)據(jù)到不同的內(nèi)存通道并優(yōu)先調(diào)度非訪存密集型應(yīng)用的訪存請(qǐng)求。Jeong等[10]提出一種通過(guò)在多核之間隔離內(nèi)存Bank以隔離訪存請(qǐng)求從而減少局部性沖突的方法。為了彌補(bǔ)因此而損失的bank級(jí)并行性,該方法采用Memory Subranking技術(shù)來(lái)增加獨(dú)立的Bank數(shù)。
Kyu Ho Park等[11]提出了一種簡(jiǎn)單的基于頁(yè)面訪問(wèn)頻度的冷熱頁(yè)面劃分策略。通過(guò)設(shè)置一個(gè)訪問(wèn)位來(lái)統(tǒng)計(jì)頁(yè)面的訪問(wèn)頻繁程度來(lái)劃分冷頁(yè)面和熱頁(yè)面。Dong-Jae Shin等[12]提出了一種更為準(zhǔn)確反映頁(yè)面熱度的頁(yè)面劃分策略。通過(guò)擴(kuò)展頁(yè)表的條目,增加了4個(gè)記錄位,越是靠左的位權(quán)重更小:8、4、2、1,每當(dāng)頁(yè)面被訪問(wèn)的時(shí)候標(biāo)記就會(huì)左移一位,最后劃分的時(shí)候計(jì)算頁(yè)面的總權(quán)重,根據(jù)設(shè)定的冷熱頁(yè)面的閾值來(lái)劃分冷熱頁(yè)面。Luiz Ramos等[13]提出了一種考慮頁(yè)面訪問(wèn)頻度和時(shí)間的RaPP策略。策略利用一個(gè)M級(jí)的LRU隊(duì)列來(lái)記錄頁(yè)面的訪問(wèn)信息,頁(yè)面在生存時(shí)間內(nèi)隨著被訪問(wèn)的程度不斷地提高隊(duì)列等級(jí)。當(dāng)超過(guò)生存時(shí)間后降低隊(duì)列等級(jí),全面地考慮頁(yè)面在很長(zhǎng)時(shí)間和最近時(shí)間段的訪問(wèn)情況。
隨著大數(shù)據(jù)技術(shù)的發(fā)展傳統(tǒng)以計(jì)算為中心的系統(tǒng)架構(gòu)逐漸轉(zhuǎn)向以數(shù)據(jù)為中心。然而磁盤(pán)訪問(wèn)性能的提升遠(yuǎn)落后于CPU計(jì)算能力的提升,無(wú)法滿足大數(shù)據(jù)處理應(yīng)用的需求。字節(jié)尋址NVM具有訪問(wèn)性能高、容量大等特性,對(duì)數(shù)據(jù)密集型應(yīng)用性能的提升帶來(lái)了希望。傳統(tǒng)存儲(chǔ)架構(gòu)不利于發(fā)揮NVM的性能優(yōu)勢(shì)。本文研究如何針對(duì)NVM設(shè)計(jì)更加高效的訪存方式,從而替代DRAM。針對(duì)字節(jié)尋址NVM特性,設(shè)計(jì)相應(yīng)的文件系統(tǒng)在很大程度上提升了系統(tǒng)性能,如SCMFS、BPFS文件系統(tǒng)等。但始終將NVM當(dāng)作存儲(chǔ)使用,并沒(méi)充分挖掘NVM的優(yōu)秀特性,沒(méi)有最大限度的降低軟件系統(tǒng)的開(kāi)銷。Mnemosyne在內(nèi)核中創(chuàng)建并虛擬化一個(gè)持久區(qū)域,通過(guò)內(nèi)存映射方式將持久區(qū)域映射到用戶空間,提供應(yīng)用程序load/store方式訪問(wèn),從而直接替代DRAM。直接訪問(wèn)NVM繞過(guò)了很多軟件層包括系統(tǒng)調(diào)用、文件系統(tǒng)以及設(shè)備驅(qū)動(dòng)等,大大降低了訪問(wèn)延遲。但Mnemosyne對(duì)于NVM設(shè)備的不同種類,在內(nèi)核中如何管理并沒(méi)有研究。本文設(shè)計(jì)并實(shí)現(xiàn)的非易失性內(nèi)存卷模式將NVM設(shè)備直接替代DRAM,通過(guò)將多塊不同種類NVM組織成地址連續(xù)的持久內(nèi)存卷,并將卷映射到用戶空間。既提供了處理器load/store訪問(wèn)方式,也很好地對(duì)異構(gòu)NVM設(shè)備實(shí)現(xiàn)管理。
Linux通過(guò)虛擬內(nèi)存實(shí)現(xiàn)內(nèi)存管理,應(yīng)用程序中進(jìn)程使用虛擬地址訪問(wèn)內(nèi)存。虛擬地址也即邏輯地址,是系統(tǒng)中分段機(jī)制產(chǎn)生的段內(nèi)偏移地址部分。實(shí)際數(shù)據(jù)需要物理地址直接訪問(wèn)。物理地址是前端總線上尋址物理內(nèi)存的地址信號(hào)。虛擬地址加上相應(yīng)的段基地址就生成了線性地址,最后通過(guò)分頁(yè)機(jī)制將線性地址翻譯成物理地址。Linux操作系統(tǒng)中虛擬地址等于線性地址,所以在Linux中只需要分頁(yè)機(jī)制便能將虛擬地址轉(zhuǎn)換成物理地址。
如圖1所示,PM卷是在NVM硬件層之上建立地址連續(xù)的軟件層。在內(nèi)核中表現(xiàn)為一段地址連續(xù)的內(nèi)存空間,并和傳統(tǒng)內(nèi)存物理地址空間統(tǒng)一尋址。在系統(tǒng)中擁有一段物理地址空間,并提供內(nèi)核組件調(diào)用的接口。PM卷和異構(gòu)NVM之間通過(guò)映射算法實(shí)現(xiàn)地址翻譯,對(duì)PM卷的訪問(wèn)實(shí)際被映射到NVM設(shè)備上。最后通過(guò)內(nèi)存映射方式將PM卷映射到用戶空間,使得應(yīng)用程序能夠以load/store方式訪問(wèn)PM卷。
圖1 非易失性內(nèi)存卷模式結(jié)構(gòu)圖
非易失性內(nèi)存卷模式設(shè)計(jì)提供程序員一個(gè)持久內(nèi)存卷模式的抽象。應(yīng)用程序以load/store方式訪問(wèn)PM卷,內(nèi)核負(fù)責(zé)將多個(gè)NVM設(shè)備組織成一個(gè)地址連續(xù)的PM卷。PM卷主要實(shí)現(xiàn)了三個(gè)方面的目標(biāo)。
1) 用戶態(tài)直接訪問(wèn)持久內(nèi)存,繞過(guò)了包括系統(tǒng)調(diào)用,文件系統(tǒng)以及設(shè)備驅(qū)動(dòng)等軟件層降低訪問(wèn)延遲。
2) 設(shè)計(jì)卷到非易失性內(nèi)存設(shè)備的映射關(guān)系,降低卷到非易失性內(nèi)存的地址翻譯開(kāi)銷。
3) 一個(gè)靈活方便的卷模式管理機(jī)制,實(shí)現(xiàn)用戶態(tài)創(chuàng)建、初始化、刪除卷等。
現(xiàn)在的內(nèi)存系統(tǒng)都是多通道架構(gòu),不同通道的內(nèi)存可以被并行訪問(wèn)。一個(gè)典型的DRAM內(nèi)存模塊,通常有16個(gè)banks,而不同的bank之間也可以并行訪問(wèn)。假設(shè)系統(tǒng)中有四個(gè)內(nèi)核,且每個(gè)內(nèi)核只有一個(gè)訪存請(qǐng)求。最好的情況下,四個(gè)訪問(wèn)請(qǐng)求的數(shù)據(jù)分別位于四個(gè)不同的內(nèi)存bank中,那么四個(gè)訪問(wèn)請(qǐng)求可以并行執(zhí)行。最壞的情況下,來(lái)自于四個(gè)內(nèi)核的訪存請(qǐng)求都指向同一個(gè)內(nèi)存bank,此時(shí)只能執(zhí)行其中一個(gè)請(qǐng)求,其他請(qǐng)求需要等待并按順序執(zhí)行,無(wú)法并行執(zhí)行。因而訪存延遲會(huì)成倍增加。大數(shù)據(jù)時(shí)代背景下,數(shù)據(jù)規(guī)模越來(lái)越大,而對(duì)數(shù)據(jù)的訪問(wèn)更多集中在對(duì)數(shù)據(jù)的讀取上。由于緩存容量有限,大量的數(shù)據(jù)訪問(wèn)是以內(nèi)存為主。在多核環(huán)境中熱數(shù)據(jù)的頻繁訪問(wèn)會(huì)導(dǎo)致同一時(shí)刻不在同一cache line但位于同一內(nèi)存bank中的數(shù)據(jù)被多個(gè)訪存用戶同時(shí)請(qǐng)求訪問(wèn),這些訪存請(qǐng)求無(wú)法并行訪問(wèn),因此導(dǎo)致嚴(yán)重訪存沖突,極大地增加了系統(tǒng)訪問(wèn)延遲。
針對(duì)熱數(shù)據(jù)頻繁訪問(wèn)導(dǎo)致的嚴(yán)重訪存沖突,考慮將頻繁訪問(wèn)的熱數(shù)據(jù)備份多次放置在不同內(nèi)存通道或不同內(nèi)存bank上。多核環(huán)境中,對(duì)于同一塊數(shù)據(jù)的多個(gè)訪問(wèn)請(qǐng)求分配到不同的數(shù)據(jù)備份上,實(shí)現(xiàn)并行訪問(wèn),降低系統(tǒng)訪問(wèn)延遲。由于數(shù)據(jù)有多個(gè)備份,對(duì)內(nèi)存容量要求很高,鑒于NVM容量很大,因而使用NVM替代DRAM,將同一塊數(shù)據(jù)備份多次,每個(gè)數(shù)據(jù)備份放置在不同的非易失性內(nèi)存設(shè)備上,并且使不同的NVM位于不同的內(nèi)存通道上。當(dāng)同一時(shí)刻對(duì)同一塊數(shù)據(jù)有多個(gè)訪問(wèn)請(qǐng)求時(shí),將訪問(wèn)映射到存有不同數(shù)據(jù)備份的NVM上。在多核環(huán)境中,不同的處理器處理其中一個(gè)訪存請(qǐng)求,可以實(shí)現(xiàn)對(duì)同一塊數(shù)據(jù)的并行訪問(wèn)。借助非易失性內(nèi)存卷模式,在位于不同內(nèi)存通道的NVM設(shè)備之上建立一個(gè)地址連續(xù)的PM卷層,對(duì)于PM卷中的每一頁(yè)映射到不同內(nèi)存通道NVM設(shè)備的多個(gè)頁(yè)面。
假設(shè)PM卷中頁(yè)面是熱數(shù)據(jù)頁(yè)面,在大量數(shù)據(jù)訪問(wèn)時(shí)會(huì)產(chǎn)生嚴(yán)重訪存沖突,所以將PM卷中的頁(yè)面映射到多個(gè)不同NVM設(shè)備上。并在設(shè)計(jì)一對(duì)多映射時(shí)將每一個(gè)NVM設(shè)備的大小看作與PM卷相同。類似于傳統(tǒng)內(nèi)存訪問(wèn)的請(qǐng)求分頁(yè)方式,通過(guò)建立頁(yè)表機(jī)制實(shí)現(xiàn)一對(duì)多地址映射。頁(yè)表中頁(yè)表項(xiàng)按照PM卷地址由小到大依次存儲(chǔ)。但由于PM卷上的每一頁(yè),可以映射到多個(gè)NVM設(shè)備,每個(gè)PM卷頁(yè)面可以對(duì)應(yīng)多個(gè)頁(yè)表項(xiàng),對(duì)應(yīng)于同一個(gè)PM卷頁(yè)的多個(gè)頁(yè)表項(xiàng)按照頁(yè)表項(xiàng)對(duì)應(yīng)NVM設(shè)備的設(shè)備號(hào)由小到大依次存儲(chǔ)。
以PM卷和非易失性內(nèi)存的地址都用32 bit表示,并且建立的頁(yè)表中的每一個(gè)頁(yè)表項(xiàng)都是32 bit,而系統(tǒng)是以4 KB為一頁(yè)大小,給出頁(yè)表項(xiàng)的格式如圖2所示。地址中12-31位表示物理頁(yè)號(hào),指向NVM中某一頁(yè)的基地址,要求物理頁(yè)4 KB對(duì)齊。由于頁(yè)表項(xiàng)前20位是頁(yè)幀號(hào),后12位并沒(méi)有實(shí)際意義,取其中一位標(biāo)記此頁(yè)是否已經(jīng)被映射,就是V字段,當(dāng)為1的時(shí)候表示已經(jīng)映射。創(chuàng)建PM卷的時(shí)候初始化頁(yè)表項(xiàng),將所有的頁(yè)表項(xiàng)初始化為0。建立的頁(yè)表映射都是固定的,一旦某個(gè)進(jìn)程訪問(wèn)了PM卷的某一頁(yè),通過(guò)一對(duì)多映射將地址映射到某個(gè)NVM設(shè)備某頁(yè)之后,在此進(jìn)程結(jié)束之前,該映射的頁(yè)表項(xiàng)保持不變。
圖2 一級(jí)頁(yè)表結(jié)構(gòu)的頁(yè)表項(xiàng)含義圖
建立了頁(yè)表機(jī)制,并初始化頁(yè)表項(xiàng)為0。當(dāng)有進(jìn)程首次對(duì)PM卷某頁(yè)寫(xiě)入數(shù)據(jù)時(shí),將數(shù)據(jù)寫(xiě)入構(gòu)成卷的第一個(gè)NVM設(shè)備上(由于構(gòu)成卷的NVM設(shè)備是用鏈表鏈接,鏈表是按照NVM設(shè)備號(hào)的大小鏈接,第一個(gè)設(shè)備指的是鏈表中第一個(gè)結(jié)點(diǎn)),之后將數(shù)據(jù)拷貝到其他k個(gè)設(shè)備上。通過(guò)寫(xiě)入的PM卷地址計(jì)算得到對(duì)應(yīng)的頁(yè)表項(xiàng)的位置,然后將每個(gè)數(shù)據(jù)備份的物理頁(yè)幀號(hào)根據(jù)設(shè)備號(hào)寫(xiě)入正確的頁(yè)表項(xiàng)中。有了映射頁(yè)表,在大規(guī)模數(shù)據(jù)讀取時(shí),需要設(shè)計(jì)地址翻譯策略,來(lái)實(shí)現(xiàn)并行的訪問(wèn)。一對(duì)多地址映射算法見(jiàn)表1。
表1 一對(duì)多地址映射算法偽代碼
因?yàn)椴煌脚_(tái)的頁(yè)面大小不盡相同,偽代碼中的PAGE_SHIFT是地址中頁(yè)面偏移量的位數(shù)。Nums指的是PM卷的一頁(yè)究竟映射到多少個(gè)NVM設(shè)備上。1~4行代碼通過(guò)頁(yè)表基址加上PFN*Nums的方式找到頁(yè)表項(xiàng)。函數(shù)isValidEntry通過(guò)檢查V標(biāo)記位是否為1來(lái)判斷頁(yè)表項(xiàng)是否有效,如果是1則表示該頁(yè)表項(xiàng)無(wú)效。searchValidEntry函數(shù)尋找下一個(gè)有效的頁(yè)表項(xiàng),函數(shù)setEntryNotValid將V標(biāo)記位設(shè)置為1。pfn_to_page函數(shù)將NVM設(shè)備的pfn轉(zhuǎn)化成對(duì)應(yīng)頁(yè)的page。算法的整體思路是:通過(guò)PM卷中待映射的頁(yè)幀號(hào)相對(duì)于PM卷初始地址頁(yè)幀號(hào)的偏移量乘以構(gòu)成PM卷的NVM設(shè)備總數(shù),再加上頁(yè)表基地址得到待映射頁(yè)對(duì)應(yīng)頁(yè)表項(xiàng)集的初始地址,然后判斷該頁(yè)表項(xiàng)是否已經(jīng)被分配給某進(jìn)程,最后找到?jīng)]有被分配的頁(yè)表項(xiàng),將該頁(yè)表項(xiàng)設(shè)置為已分配,同時(shí)通過(guò)頁(yè)表項(xiàng)前20位頁(yè)面物理地址得到頁(yè)幀號(hào)。
由于頁(yè)表的大小會(huì)隨著PM卷地址空間大小的增加成倍增加,因而增加缺頁(yè)開(kāi)銷,所以考慮將頁(yè)表設(shè)計(jì)成多級(jí)結(jié)構(gòu)。若設(shè)計(jì)成二級(jí)頁(yè)表,對(duì)應(yīng)PM卷地址結(jié)構(gòu)如圖3所示。以一對(duì)四映射為例,頁(yè)表項(xiàng)中是4個(gè)頁(yè)表項(xiàng)指向同一個(gè)PM卷地址頁(yè)框,那么在一頁(yè)中(4 KB)可放入256個(gè)(一個(gè)頁(yè)表項(xiàng)占4 B,4 KB/(4 B×4))映射到不同PM卷地址的頁(yè)表項(xiàng),所以需要8位來(lái)標(biāo)記,也即是圖3中的PPN2(physical page number),一級(jí)頁(yè)表用12位,也即是圖3中的PPN1來(lái)標(biāo)記,需要存儲(chǔ)在4頁(yè)中。
圖3 二級(jí)頁(yè)表結(jié)構(gòu)的PM卷地址含義圖
一對(duì)多地址映射由于在多塊NVM上建立了PM卷層,并且PM卷層到NVM設(shè)備之間通過(guò)頁(yè)表形式進(jìn)行地址翻譯,相比于傳統(tǒng)內(nèi)存架構(gòu),多了一層地址翻譯過(guò)程。傳統(tǒng)內(nèi)存架構(gòu)中應(yīng)用程序虛擬地址在MMU作用下最多只需要一次訪存操作便可以得到物理地址,而非易失性內(nèi)存卷模式下的一對(duì)多地址映射中。應(yīng)用程序虛擬地址首先需要類似于傳統(tǒng)內(nèi)存架構(gòu)中地址翻譯過(guò)程得到PM卷對(duì)應(yīng)的地址,然后仍需要進(jìn)行PM卷到NVM地址映射得到最終存儲(chǔ)數(shù)據(jù)的NVM設(shè)備上地址,至少需要兩次訪存操作。這會(huì)導(dǎo)致缺頁(yè)處理開(kāi)銷加大。
多路并行訪存是將數(shù)據(jù)備份放置在不同內(nèi)存通道的NVM上,在多核環(huán)境中通過(guò)一對(duì)多映射算法,將同一塊數(shù)據(jù)不同訪存請(qǐng)求分配到不同數(shù)據(jù)備份上,實(shí)現(xiàn)并行訪問(wèn)。首先實(shí)現(xiàn)非易失性內(nèi)存卷模式,然后實(shí)現(xiàn)PM卷到NVM之間一對(duì)多地址映射。
為了對(duì)PM卷進(jìn)行管理,在內(nèi)核中創(chuàng)建結(jié)構(gòu)體struct pm_volume保存PM卷的卷大小、卷號(hào)、卷的開(kāi)始地址以及組成卷的NVM設(shè)備等信息。同時(shí)PM卷是取自不同NVM設(shè)備的中的一部分內(nèi)存空間組成,因此創(chuàng)建結(jié)構(gòu)體struct pm_device保存組成PM卷的NVM設(shè)備開(kāi)始頁(yè)號(hào)、大小、設(shè)備號(hào)等信息。實(shí)現(xiàn)非易失性內(nèi)存卷模式分兩步進(jìn)行,首先將PM卷加入內(nèi)存系統(tǒng)中,提供內(nèi)核中組件訪問(wèn)接口。然后通過(guò)內(nèi)存映射方式將PM卷映射到用戶地址空間,提供應(yīng)用程序load/stroe訪問(wèn)方式。
(1) 將PM卷加入內(nèi)存系統(tǒng)分兩步實(shí)現(xiàn),首先將PM卷加入伙伴系統(tǒng),然后修改內(nèi)核中alloc_pages函數(shù)使內(nèi)核組件能夠訪問(wèn)PM卷。
傳統(tǒng)內(nèi)存系統(tǒng)中,內(nèi)核將內(nèi)存空間劃分成結(jié)點(diǎn),每個(gè)結(jié)點(diǎn)劃分成管理區(qū)(zone),每個(gè)管理區(qū)由各自的伙伴系統(tǒng)負(fù)責(zé)所有頁(yè)面的申請(qǐng)和釋放。管理區(qū)中的每個(gè)頁(yè)幀對(duì)應(yīng)一個(gè)struct page結(jié)構(gòu)。我們自定義了PM_ZONE管理區(qū),讓PM卷和PM_ZONE管理區(qū)的頁(yè)面一一對(duì)應(yīng),然后將PM_ZONE管理區(qū)中的頁(yè)面加入伙伴系統(tǒng)。通過(guò)修改管理區(qū)和伙伴系統(tǒng)初始化方法,加入對(duì)自定義PM_ZONE的管理。為了方便區(qū)分PM_ZONE和系統(tǒng)其他管理區(qū),在struct zone結(jié)構(gòu)體中增加了char*name字段表示管理區(qū)的名字。完成管理區(qū)和伙伴系統(tǒng)初始化之后,PM_ZONE管理區(qū)上并沒(méi)有實(shí)際頁(yè)面,所以內(nèi)核中申請(qǐng)PM_ZONE大小的連續(xù)內(nèi)存頁(yè),將其每頁(yè)初始化為屬于PM_ZONE管理區(qū)。由于申請(qǐng)和釋放頁(yè)面時(shí)系統(tǒng)通過(guò)page_zone(page)函數(shù)獲取頁(yè)所在的管理區(qū),但該函數(shù)用到很多系統(tǒng)預(yù)定義標(biāo)記符,而PM_ZONE并沒(méi)有添加到系統(tǒng)中維護(hù),因此無(wú)法通過(guò)此方法獲取頁(yè)所在的管理區(qū),故在struct page中添加了一個(gè)struct zone*zone字段來(lái)表示該頁(yè)所在的管理區(qū)。在內(nèi)核申請(qǐng)PM_ZONE大小頁(yè)面并設(shè)置成所屬管理區(qū)時(shí),通過(guò)page->zone->name=″PM_ZONE″實(shí)現(xiàn)。
PM卷以PM_ZONE管理區(qū)的形式加入內(nèi)存伙伴系統(tǒng)之后,需修改內(nèi)核的alloc_pages函數(shù)才能使內(nèi)核申請(qǐng)PM卷的頁(yè)面。實(shí)現(xiàn)中增加自定義GFP_PM標(biāo)志,也就是將GFP_PM標(biāo)志加入alloc_pages函數(shù)第一個(gè)參數(shù)gfp_t gfp_mask中。通過(guò)判斷gfp_mask標(biāo)志是否等于GFP_PM,進(jìn)而選擇是否從PM卷對(duì)應(yīng)的PM_ZONE管理區(qū)中申請(qǐng)頁(yè)面。
(2) PM卷以PM_ZONE管理區(qū)形式加入內(nèi)存系統(tǒng)之后,內(nèi)核可以申請(qǐng)釋放PM卷中頁(yè)面。但應(yīng)用程序?qū)M卷的訪問(wèn)還需要提供正確的訪問(wèn)接口,本文基于mmap的內(nèi)存映射接口模式,將PM卷層中的頁(yè)面通過(guò)mmap函數(shù)映射到用戶空間。基于mmap的內(nèi)存映射方式是指通過(guò)mmap函數(shù)將PM卷地址空間映射到用戶進(jìn)程地址空間,提供用戶進(jìn)程load/store方式訪問(wèn)。函數(shù)接口形式是int pm_mmap(struct file*filp, struct vm_area_struct*vma),參數(shù)filp是待映射目標(biāo)文件的結(jié)構(gòu)體指針,vma是虛擬內(nèi)存區(qū)域。
一對(duì)多地址映射通過(guò)頁(yè)表機(jī)制實(shí)現(xiàn),本文實(shí)現(xiàn)了單級(jí)頁(yè)表結(jié)構(gòu)。首先在PM卷結(jié)構(gòu)體struct pm_volume中加入屬性u(píng)nsigned long*pageTableBase表示當(dāng)前PM卷對(duì)應(yīng)頁(yè)表基地址。由于struct pm_volume結(jié)構(gòu)體中有屬性volume_size表示PM卷大小以及num表示構(gòu)成卷的NVM設(shè)備個(gè)數(shù)。volume_size和num乘積就是頁(yè)表大小。另外還需在struct page結(jié)構(gòu)體中增加屬性u(píng)nsigned int firstaccess,表示PM卷中每頁(yè)是否第一次被進(jìn)程訪問(wèn)并寫(xiě)入數(shù)據(jù)。0表示首次被訪問(wèn),1表示否。
創(chuàng)建PM卷時(shí)根據(jù)頁(yè)表大小將所有頁(yè)表項(xiàng)初始化為0。當(dāng)有進(jìn)程首次訪問(wèn)PM卷的某頁(yè)時(shí),修改mmap函數(shù),通過(guò)判斷PM卷的當(dāng)前被寫(xiě)入頁(yè)面的struct page的firstaccess屬性是否為0,決定是將數(shù)據(jù)直接寫(xiě)入第一個(gè)NVM設(shè)備的對(duì)應(yīng)頁(yè)還是訪問(wèn)頁(yè)表得到頁(yè)表項(xiàng)。如果是0,表示訪問(wèn)的PM卷頁(yè)面是首次寫(xiě)入,因此將數(shù)據(jù)寫(xiě)入第一個(gè)NVM設(shè)備對(duì)應(yīng)頁(yè)。然后通過(guò)memcpy函數(shù)將該頁(yè)數(shù)據(jù)拷貝到其他NVM設(shè)備對(duì)應(yīng)頁(yè)面上。Memcpy函數(shù)使用內(nèi)存虛擬地址,可通過(guò)函數(shù)kmap將NVM設(shè)備物理地址轉(zhuǎn)換成內(nèi)存虛擬地址。最后修改PM卷中當(dāng)前頁(yè)面的頁(yè)表項(xiàng)集。
建立頁(yè)表后,對(duì)PM卷該頁(yè)面的大量讀取操作可以通過(guò)地址翻譯算法在多核環(huán)境中實(shí)現(xiàn)并行訪問(wèn)。以PM卷映射到四個(gè)NVM設(shè)備為例子闡述地址翻譯的實(shí)現(xiàn)過(guò)程,考慮到非易失性內(nèi)存總的空間大小是PM卷的4倍,在制作頁(yè)表時(shí)PM卷的每一個(gè)頁(yè)號(hào)對(duì)應(yīng)四個(gè)不同NVM的頁(yè)號(hào),PM卷每一頁(yè)對(duì)應(yīng)的四個(gè)不同的NVM頁(yè)號(hào)的頁(yè)表?xiàng)l目連續(xù)(每個(gè)頁(yè)表?xiàng)l目的大小為4 B)。若PM卷的大小為4 GB,每個(gè)NVM的大小同樣也是4 GB。以PM卷地址為:0x000645b0為例,一對(duì)四地址翻譯如圖4所示。對(duì)應(yīng)PM卷地址的頁(yè)表項(xiàng)有4個(gè)(圖中只畫(huà)出3個(gè)),地址0x000645b0前20位的物理頁(yè)號(hào)是100,根據(jù)算法乘以4得到400。查看頁(yè)表400位置處對(duì)應(yīng)的V標(biāo)記位是1,表示此頁(yè)表項(xiàng)已經(jīng)被映射,由searchValidEntry函數(shù)找到401處V標(biāo)記位是0有效,則將該標(biāo)記位設(shè)置為1,并且根據(jù)該頁(yè)表項(xiàng)的前二十位頁(yè)面物理基地址找到對(duì)應(yīng)的NVM設(shè)備的那一頁(yè),再由offset為1 456計(jì)算得到最終目標(biāo)字節(jié)位置并找到。
圖4 一對(duì)四單級(jí)頁(yè)表結(jié)構(gòu)圖,左邊是頁(yè)表結(jié)構(gòu),右邊是找到的NVM設(shè)備的具體物理頁(yè)
一旦將某個(gè)非易失性內(nèi)存的頁(yè)幀號(hào)映射給對(duì)應(yīng)進(jìn)程的時(shí)候,當(dāng)該進(jìn)程此后訪問(wèn)PM卷同一頁(yè)時(shí),一律訪問(wèn)之前綁定的非易失性內(nèi)存的頁(yè),而不再進(jìn)行缺頁(yè)處理,也就是缺頁(yè)處理只會(huì)在進(jìn)程首次訪問(wèn)PM卷地址空間某一頁(yè)的時(shí)候進(jìn)行。即便缺頁(yè)訪問(wèn)時(shí),需要進(jìn)行兩次的地址翻譯,當(dāng)有大量的數(shù)據(jù)訪問(wèn)時(shí)候,這個(gè)缺頁(yè)的開(kāi)銷會(huì)被不斷稀釋掉。
實(shí)驗(yàn)中,硬件是ThinkPad x230 Intel i5雙核4 GB DDR3雙通道內(nèi)存筆記本電腦,安裝了Ubuntu15.10操作系統(tǒng),內(nèi)核版本是4.2.8。
在驗(yàn)證了非易失性內(nèi)存卷模式實(shí)現(xiàn)的合理性后,驗(yàn)證一對(duì)多地址映射。從內(nèi)存DRAM中申請(qǐng)兩個(gè)連續(xù)內(nèi)存塊模擬兩個(gè)NVM設(shè)備。由于一對(duì)多設(shè)計(jì)比傳統(tǒng)內(nèi)存訪問(wèn)方式多了一層地址翻譯過(guò)程,因而首先考慮缺頁(yè)中斷處理中開(kāi)銷的增加對(duì)系統(tǒng)的影響。實(shí)驗(yàn)組中測(cè)量的是實(shí)現(xiàn)了一對(duì)多映射的缺頁(yè)處理時(shí)間,對(duì)照組測(cè)量傳統(tǒng)內(nèi)存請(qǐng)求分頁(yè)方式缺頁(yè)處理時(shí)間。實(shí)驗(yàn)結(jié)果見(jiàn)圖5。
圖5 性能優(yōu)化后PM卷頁(yè)面訪問(wèn)缺頁(yè)處理時(shí)間和正常內(nèi)存訪問(wèn)缺頁(yè)處理時(shí)間對(duì)比圖
缺頁(yè)處理的開(kāi)銷會(huì)增加,但由于頁(yè)表項(xiàng)一旦寫(xiě)進(jìn)頁(yè)表,在當(dāng)前進(jìn)程結(jié)束前頁(yè)表項(xiàng)不會(huì)改變,所以缺頁(yè)只在首次訪問(wèn)PM卷頁(yè)面時(shí)發(fā)生。在大規(guī)模數(shù)據(jù)讀取時(shí)開(kāi)銷會(huì)被不斷稀釋,因此進(jìn)一步測(cè)試對(duì)PM卷大規(guī)模數(shù)據(jù)訪問(wèn)時(shí)的性能提升情況。實(shí)驗(yàn)主要驗(yàn)證一對(duì)二地址映射時(shí),雙通道并行訪問(wèn)是否能夠提升系統(tǒng)性能,因而,對(duì)于映射到不同內(nèi)存通道的同一塊數(shù)據(jù)的兩個(gè)備份不要求數(shù)據(jù)相同,主要保證兩個(gè)數(shù)據(jù)備份位于不同內(nèi)存通道即可。
內(nèi)存控制器地址映射,是將一個(gè)內(nèi)存請(qǐng)求的物理地址翻譯并映射成DRAM模塊的物理結(jié)構(gòu):channel、rank、bank、column等。對(duì)于雙通道的內(nèi)存結(jié)構(gòu)中,物理地址有1 bit表示該內(nèi)存請(qǐng)求的數(shù)據(jù)所在內(nèi)存通道。實(shí)驗(yàn)中使用的ThinkPad x230設(shè)備是物理地址右邊起第12 bit。
一對(duì)二地址映射實(shí)驗(yàn)中訪問(wèn)不同內(nèi)存通道便可以通過(guò)訪問(wèn)物理地址channel標(biāo)記位分別為0和1的兩個(gè)內(nèi)存通道。也就是一對(duì)二設(shè)計(jì)中同一PM卷頁(yè)面映射的兩個(gè)實(shí)際頁(yè)面的頁(yè)幀號(hào)倒數(shù)第2 bit不相同。實(shí)驗(yàn)中設(shè)計(jì)兩個(gè)并發(fā)的線程,分別讀取PM卷空間的一段頁(yè)框。由于實(shí)現(xiàn)了一對(duì)二的情況,當(dāng)訪問(wèn)同一塊數(shù)據(jù)時(shí)兩個(gè)并發(fā)線程會(huì)實(shí)現(xiàn)并行執(zhí)行。對(duì)照組中將與一對(duì)多中PM卷大小相同的一塊連續(xù)內(nèi)存通過(guò)mmap函數(shù)映射到進(jìn)程虛擬地址空間,設(shè)計(jì)兩個(gè)線程執(zhí)行并發(fā)訪問(wèn)。實(shí)驗(yàn)是在禁用cache中進(jìn)行。實(shí)驗(yàn)是將每一個(gè)線程對(duì)PM卷進(jìn)行100萬(wàn)次讀取操作,測(cè)量?jī)蓚€(gè)線程執(zhí)行完需要的總時(shí)間,與對(duì)照組總時(shí)間進(jìn)行對(duì)比。結(jié)果如表2所示。
表2 實(shí)驗(yàn)結(jié)果匯總表 us
如圖5缺頁(yè)處理實(shí)驗(yàn)共進(jìn)行了15組,實(shí)驗(yàn)組數(shù)據(jù)的最大值、最小值和平均值分別是9 514 ns、5 255 ns和6 917.9 ns。對(duì)照組數(shù)據(jù)的最大值、最小值和平均值分別是1 693 ns、322 ns和550.4 ns。從平均值看來(lái),實(shí)驗(yàn)組所用時(shí)間是對(duì)照組的12.6倍??梢钥闯鲈谌表?yè)處理上對(duì)性能產(chǎn)生了較大的影響。針對(duì)一對(duì)多地址映射進(jìn)行了22組實(shí)驗(yàn)得到數(shù)據(jù),見(jiàn)表2。
表2中實(shí)驗(yàn)組數(shù)據(jù)的平均值、最大值和最小值分別是:11 430.8 us、14 728 us、9 496 us。對(duì)照組數(shù)據(jù)平均值、最大值和最小值分別是:12 324.9 us、15 968 us、9 889 us。由平均值可計(jì)算得出實(shí)驗(yàn)組比對(duì)照組性能提升7.25%。從實(shí)驗(yàn)結(jié)果看來(lái),基于一對(duì)多映射的PM卷模式增加了一層地址翻譯過(guò)程雖然在缺頁(yè)處理時(shí)間上是傳統(tǒng)訪存方式的12.6倍,但在大量數(shù)據(jù)讀取中,整體性能提升了7.25%。但是仍然存在些不足之處,實(shí)驗(yàn)是在雙通道環(huán)境下進(jìn)行的,實(shí)現(xiàn)了一對(duì)二映射的情況,對(duì)于更多的一對(duì)三、一對(duì)四等映射情況可進(jìn)一步進(jìn)行實(shí)驗(yàn)。
本文針對(duì)新型NVM設(shè)備的優(yōu)秀特性,設(shè)計(jì)實(shí)現(xiàn)了load/store方式訪問(wèn)NVM設(shè)備,并管理異構(gòu)的NVM設(shè)備的非易失性內(nèi)存卷。然后基于熱數(shù)據(jù)訪存沖突在非易失性內(nèi)存卷模式的基礎(chǔ)上提出了一對(duì)多的地址映射方案,實(shí)現(xiàn)了一對(duì)多地址映射策略。最后,通過(guò)在雙通道內(nèi)存中,進(jìn)行一對(duì)二映射實(shí)驗(yàn),得到的數(shù)據(jù)在一對(duì)二映射情況下,系統(tǒng)訪存性能提升了7.25%。表明這種設(shè)計(jì)確實(shí)能夠改變內(nèi)存訪問(wèn)方式并提升訪問(wèn)性能,比較好地避免熱數(shù)據(jù)的訪存沖突。