余海濤
摘? ?要:近年來,研究者針對持久性內(nèi)存的管理做了許多工作,但仍存在一些問題,比如未考慮數(shù)據(jù)一致性、讀寫不對稱和非均勻存儲器存取特性。文章提出了一種高效的持久性內(nèi)存管理系統(tǒng),設計了基于內(nèi)存緩存的一致性策略,和基于非均勻存儲器存取特性的多粒度內(nèi)存管理策略。測試結果表明,在多線程下,分配內(nèi)存大小為64字節(jié)時,相比于Makalu,持久性內(nèi)存管理系統(tǒng)的平均性能提高了38.6%。
關鍵詞:持久性內(nèi)存;一致性;可擴展性
近年來,持久性內(nèi)存得到了快速地發(fā)展,具有非易失性、字節(jié)尋址和讀寫性能,與將動態(tài)隨機存取存儲器(Dynamic Random Access Memory,DRAM)有相似的優(yōu)勢,但是也存在讀寫性能不對稱、耐久度較弱等缺陷。本文針對以上問題,提出了一種高效的持久性內(nèi)存管理系統(tǒng)(Persistent Memory Management System,PMMS),設計了基于內(nèi)存緩存的一致性策略,通過DRAM作為緩存,縮短持久化的路徑,減少一致性開銷;設計了基于非均勻存儲器存取(Non-Uniform Memory Access,NUMA)特性的多粒度分配與釋放策略,通過將NUMA特性與多粒度內(nèi)存操作相結合,保證了系統(tǒng)在多線程下內(nèi)存分配與釋放的高效性;設計了基于寫入時間間隔和閾值相結合的磨損均衡策略,通過預先設定持久性內(nèi)存塊的時間間隔和閾值,來保障持久性內(nèi)存塊的磨損均衡。
1? ? 持久性內(nèi)存管理系統(tǒng)結構設計
根據(jù)PMMS的特性,本系統(tǒng)結構可分為三大模塊:內(nèi)存一致性管理模塊、分配與釋放管理模塊和磨損均衡管理模塊,該系統(tǒng)結構如圖1所示。
1.1? 內(nèi)存一致性管理模塊
CPU的亂序執(zhí)行指令會造成數(shù)據(jù)寫入持久性內(nèi)存的不一致性問題,因此,需要顯示同步執(zhí)行的緩存刷寫指令,將數(shù)據(jù)從高速緩存刷寫至持久性內(nèi)存。一方面,此類指令開銷高昂,嚴重影響了CPU的執(zhí)行效率;另一方面,持久性內(nèi)存的讀寫性能相比于DRAM較弱,直接將數(shù)據(jù)寫至持久性內(nèi)存會造成嚴重的讀寫延遲。因此,本文設計了基于內(nèi)存緩存的一致性策略,使用DRAM作為持久性內(nèi)存的緩存,將數(shù)據(jù)和日志先寫入DRAM,然后通過后臺線程異步寫入持久性內(nèi)存,來保證系統(tǒng)的一致性。針對每一次操作,本系統(tǒng)首先將其記錄至日志,日志內(nèi)容為操作的類型、地址和內(nèi)存大小,然后將日志使用后臺線程異步寫回至持久性內(nèi)存,不會影響本系統(tǒng)主線程的分配與釋放性能,最后將數(shù)據(jù)以同樣的方式寫至持久性內(nèi)存。
1.2? 分配與釋放管理模塊
內(nèi)存的分配與釋放作為底層基礎操作,對上層應用的性能有著關鍵的影響。首先,需要保障內(nèi)存分配與釋放的速度。其次,現(xiàn)在計算機大部分具有多個CPU,它們之間的訪問存在延遲不均的情況,不考慮這種特性將會影響內(nèi)存分配與釋放的性能。為此,本文設計了基于NUMA特性的多粒度分配與釋放策略。
本文利用系統(tǒng)函數(shù)申請8 GB的虛擬地址空間,由于虛擬地址只有在真正被使用的時候才會映射到對應的物理地址,所以在64位的操作系統(tǒng)中不必擔心地址空間不足的問題。本系統(tǒng)將申請的內(nèi)存對象分為3個粒度,分別是小粒度(小于4 KB)、中等粒度(4 KB到2 MB)和大粒度(大于2 MB);定義多粒度內(nèi)存管理單元,分別有page(4 KB),chunk(128 KB)和block(4 MB)。針對小粒度對象,本系統(tǒng)將其劃分為不同的級別,用數(shù)組保存級別,例如,8字節(jié)、16字節(jié)、32字節(jié)等,當收到待分配請求時,本系統(tǒng)首先計算該申請對象的內(nèi)存粒度,然后再計算其大小級別。若為小粒度對象,則從DRAM小粒度對象級別的雙向鏈表中分配一個條目。針對中等粒度對象,本系統(tǒng)分配多個chunk的方式滿足其分配請求。針對大粒度對象,本系統(tǒng)使用操作系統(tǒng)大頁的方式處理。在虛擬內(nèi)存管理中,虛擬地址到物理地址的映射轉換過程由內(nèi)核管理,對于每一個頁面的轉換,內(nèi)核需要查詢對應的映射表,系統(tǒng)頁面默認大小為4 KB,當申請的內(nèi)存塊較大時,內(nèi)核需要查詢更多的映射表,這樣會占用更多的內(nèi)存,降低系統(tǒng)的性能。所以,針對大粒度對象的分配操作,使用系統(tǒng)的大頁處理,盡可能降低系統(tǒng)的頁面載入和查詢開銷,提高分配大內(nèi)存塊的速度。設置大頁為2 MB,使用madvise函數(shù)的方式向內(nèi)核申請以大頁的方式映射內(nèi)存,當申請的內(nèi)存對象大于2 MB時,使用2 MB對齊分配,充分利用虛擬地址延遲映射物理內(nèi)存的機制。分配操作步驟為:首先獲取DRAM中空閑塊地址,然后將該分配信息寫入日志,最后將地址返回給應用程序。釋放操作的步驟為:首先讀取該釋放塊的頭文件,然后獲取釋放塊的大小,最后將該塊添加至DRAM對應的雙向鏈表。
針對NUMA特性,本系統(tǒng)設計了線程綁核策略,將線程綁定至CPU核心,使得線程優(yōu)先分配本地核心所在的內(nèi)存,如果不能滿足請求則分配遠端內(nèi)存。針對多線程之間的擴展性,本文設計了線程本地存儲策略,使用Hoard[1]中相似的思想,將持久性內(nèi)存分為全局堆和線程堆,線程堆內(nèi)的分配與釋放操作不需要加鎖,這減少了線程間的資源競爭開銷。
1.3? 磨損均衡管理模塊
相比于DRAM,磨損均衡管理模塊持久性內(nèi)存的耐久性較弱,因此,需要均衡的寫入持久性內(nèi)存。本系統(tǒng)設計了基于寫入時間間隔和閾值相結合的磨損均衡策略,需要預先設置持久性內(nèi)存塊以及兩次被寫入的時間間隔和閾值,記錄不同粒度的內(nèi)存塊記錄寫入的時間戳和寫入次數(shù)。當達到時間間隔時,該內(nèi)存塊才能被再次分配,分配時需要按照該內(nèi)存塊磨損值排序,然后分配磨損值最小的內(nèi)存塊。這樣可以在滿足分配要求的同時,均衡地分配持久性內(nèi)存。
本系統(tǒng)在實現(xiàn)過程中采用了優(yōu)化性能的技巧:有指令預取和日志壓縮。通過使用__builtin_expect指令使得CPU可以預取下一條指令,減少CPU等待取指令的耗時,提高CPU的效率。通過使用lz4[2]壓縮算法將日志壓縮后寫入持久性內(nèi)存,減少對持久性內(nèi)存的磨損。
2? ? 實驗測試與分析
為了分析持久性內(nèi)存管理系統(tǒng)PMMS的性能,本節(jié)將從兩個方面對PMMS進行測試與分析:(1)不同分配內(nèi)存大小下的性能對比測試。(2)在多線程下的性能對比測試。
2.1? 測試環(huán)境
本系統(tǒng)所有實驗均為相同的服務器環(huán)境,服務器配置環(huán)境如表1所示,操作系統(tǒng)為Centos 6.8,內(nèi)存為64 GB,由于目前持久性內(nèi)存尚不可用,本系統(tǒng)使用8 GB大小的DRAM模擬持久性內(nèi)存,使用RDTSC指令模擬延遲,默認情況下,將延遲設置為200 ns,實驗對比對象為持久性內(nèi)存分配器Makalu和Glibc默認分配器ptmalloc。
2.2? 不同分配內(nèi)存大小下的性能對比測試
上層應用的分配請求主要集中在小內(nèi)存塊的分配,本節(jié)測試各分配器分配內(nèi)存大小為64字節(jié)到1 024字節(jié)下的性能,單線程分配次數(shù)為20 000次,實驗結果如圖2所示。
從圖2中可得,分配內(nèi)存大小為64字節(jié)到1 024字節(jié)時,PMMS的分配時間均少于Makalu,分配內(nèi)存大小為1 024字節(jié)時,相比Makalu,PMMS的分配時間減少65%,主要是因為PMMS將DRAM作為持久性內(nèi)存的緩存和設計了多粒度的分配策略,減少了分配操作的延遲。分配內(nèi)存大小為64字節(jié)到256字節(jié)時,ptmalloc的分配時間最少,主要是因為它針對256字節(jié)以下的內(nèi)存分配設計了快速分配的數(shù)據(jù)結構,分配內(nèi)存大小高于256字節(jié)時,ptmalloc的性能不如PMMS。
2.3? 在多線程下的性能對比測試
本節(jié)測試各分配器在多線程下的性能,分配內(nèi)存大小為64字節(jié)和64~512字節(jié)之間的隨機值,實驗結果如圖3—4所示。
從圖3—4可得,在多線程下,PMMS每線程每秒的分配次數(shù)要優(yōu)于Makalu,分配內(nèi)存大小為64字節(jié)時,相比于Makalu,PMMS的平均性能提高了38.6%。主要是因為PMMS設計了基于NUMA特性的多粒度分配與釋放策略和線程本地存儲策略,減少了線程間的資源競爭,提高了CPU的處理效率。在64~512字節(jié)之間,分配隨機值時,PMMS的性能略優(yōu)于ptmalloc,主要是因為針對小粒度內(nèi)存設計了多級別更細粒度的管理,充分利用了DRAM作為緩存的優(yōu)勢。
3? ? 結語
持久性內(nèi)存的出現(xiàn)給計算機系統(tǒng)設計提出了新的挑戰(zhàn)。比如,持久性內(nèi)存的一致性和傳統(tǒng)的分配器未考慮持久性內(nèi)存的讀寫不對稱和耐久性較弱等問題。為了解決這些問題,本文設計了一種持久性內(nèi)存管理系統(tǒng)PMMS,實驗結果表明,單線程下,分配內(nèi)存大小為1 024字節(jié)時,相比于Makalu,PMMS的分配時間減少了65%;多線程下,分配內(nèi)存大小為64字節(jié)時,相比于Makalu,PMMS的平均性能提高了38.6%。
[參考文獻]
[1]BERGER E D,MCKINLEY K S,BLUMOFE R D,et al.Hoard:a scalable memory allocator for multithreaded applications[C].Cambridge:ASPLOS-IX Proceedings of the 9th International Conference on Architectural Support for Programming Languages and Operating Systems,2000.
[2]NAMELESS.Extremely fast compression algorithm[EB/OL].(2019-02-10)[2019-10-25].https://github.com/lz4/lz4.