余海濤

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