RFC-0219:Zircon Page 壓縮

RFC-0219:Zircon 頁面壓縮
狀態已接受
領域
  • 核心
說明

匿名 VMO 的網頁核心壓縮。

問題
毛皮變化
作者
審查人員
提交日期 (年-月-日)2022-05-31
審查日期 (年-月-日)2023-06-03

摘要

本文件建議新增核心壓縮和解壓縮系統 匿名使用者記憶體資料

雖然系統是核心的,但使用者空間不一定會完全透明化 避免記憶體用量計算問題除了 API 變更以外,所有功能均可正常運作 變更會包含在核心中

提振精神

Fuchsia 經常用於資源受限裝置,且具備 增加記憶體集區,將能大幅改善使用者體驗。

記憶體的核心壓縮是其他作業用 這有助於 Fuchsia 獲得同等的青睞

相關人員

講師:

cpu@google.com

審查者:

eieio@google.com、rashaeqbal@google.com、maniscalco@google.com

諮詢:

mseaborn@google.com、mvanotti@google.com、Wez@google.com、plabatut@google.com jamesr@google.com、davemoore@google.com

社交功能:

與 Zircon 共用核心設計和實作零件的 RFC 提案文件 核心團隊和廣大的利害關係人。

設計

本節將概略說明實作的高階設計選項。 。

老化與追蹤

匿名網頁的處理方式與 屬於老化,因此意味著:

  • 在匿名網頁中加入反向連結,讓 vm_page_t 能 + VmObjectPaged 可以執行偏移查詢這會增加 則每次頁面在 VMO 之間移動時反向連結。
  • 變更網頁佇列,不處理受呼叫的呼叫器和匿名頁面 有差異。

網頁佇列中的處理中,已有「有效」和「停用」集合的概念。 現有的移除項目一律不會從有效集合中移除,以免輾轉現象 條件。匿名網頁會歸在同一個佇列中,且具有相同的佇列 壓縮限制。

網頁經過壓縮後,就會從網頁佇列追蹤中移除,類似於 所排除的網頁。壓縮失敗的網頁會移到獨立清單, 將不會再次嘗試壓縮如此一來,存取這類網頁時, 移回使用中的組合,以及潛在年齡並嘗試壓縮 可以選取「重新建立」,再次生成新的提示

雖然我們只會壓縮閒置網頁,但仍會執行三次 支援服務:

  • 提高舊網頁壓縮率,即使記憶體壓力也不大,但 處理 LRU 佇列
  • 在記憶體壓力下進行壓縮,以假處分的形式執行撤銷作業。
  • 壓縮以避免 OOM。

這些觸發條件會透過核心 cmdline 標記進行切換。

VmPageList 標記

VmPageList 儲存庫需要有額外的標記類型,才能執行以下操作:

  • 表示網頁確實存在,但已經過壓縮。
  • 儲存足夠的中繼資料,以便在壓縮的儲存空間中找到網頁。

VmPageList 的項目已編碼以儲存兩個 vm_page_t 指標和零網頁標記,且可延伸 編碼。

目前網頁清單項目是 64 位元的值, 以下選項:

  • 0:項目空白
  • 最小位元 = 1:零網頁標記
  • 任何其他:指向 vm_page_t

此配置之所以能運作,是因為指標對齊方式會導致 vm_page_t 的底部 3 位元 指標一律為零因此可以將這個配置一般化 頁面清單項目底部 3 位元代表類型,其餘位元 都是關聯資料初始型別為:

  • 0:空白的輸入或 vm_page_t 指標 (視資料位元設定而定)
  • 1:零網頁標記。剩餘資料位元必須為 0。
  • 2:網頁經過壓縮。剩餘位元是從 壓縮系統
  • 3-7:目前無效的類型。

壓縮作業

將重點放在簡單有效率的初始用途。初始儲存空間用途 策略只會執行單一網頁壓縮和解壓縮作業, 依 VMO 明確將網頁分組

如未依 VMO 將頁面分組,就能以同樣的方式提供壓縮路徑 做為現有的移除系統雖然不同 VMO 的網頁 建立起因於單一儲存系統 無法在不同的 VMO 之間建立鎖定依附元件這在 防止資訊外洩,透過時間管道防止資訊外洩 且延遲時間很高

為避免不必要的鎖定爭用,請執行壓縮或 必須在不保留 VMO 鎖定的情況下進行解壓縮演算法 在保留解壓縮所需的任何鎖定時,就不應該執行壓縮。

壓縮演算法

以下是壓縮路徑的概要說明,但有錯誤 額外處理案件要壓縮的輸入內容是頁面,即所屬 VMO 加上該頁面在 VMO 中的偏移偏移量可用於驗證 取得 VMO 鎖定後,該頁面仍會保留在 VMO 中 在這個虛擬程式碼中略過的錯誤處理設定。

Take VMO lock
Update page list to use temporary compression reference
Release VMO lock
Compress page to buffer
Take compressed storage lock
Allocate storage slot
Release storage lock
Copy buffer to storage
Take VMO lock
Check page list still holds temporary compression reference
Update page list to final compression reference
Release VMO lock

一開始先使用暫時參照的動機,而不是立即使用 分配參照) 是提高壓縮後的彈性 儲存資料大小來產生參照 則會在產生參照時儲存。因此能用來 不需要間接取得資料中資料的確切位置 並加入一個額外表格

即使未使用臨時參考資料,仍會取得兩次 VMO 鎖定 這是因為,這麼做還是需要解決任何可能的競爭問題,才能使用網頁 同時進行壓縮例如,此處指的 就算是壓縮作業發生時也可能發生了錯誤 除非我們重新取得 VMO 鎖定並檢查,否則沒有這點。

由於壓縮作業進行中,由於 VMO 鎖定並未保留,因此另一個執行緒 可能會找到暫時參照並嘗試使用。做為 參照並未實際擁有可解壓縮的資料,我們有兩個 解決方法:

  • 請等待壓縮作業完成,再擷取原始網頁。
  • 複製原始頁面 (系統會預先分配這個資源的記憶體 新的要求)。

這個用意是為了確保網頁的擁有者為已知狀態,且處於已知狀態 會發生什麼情況?壓縮時使用原始網頁 表示仍有問題,原因如下:

  • 在壓縮演算法讀取網頁時修改網頁 可能表示壓縮演算法可能的錯誤和受攻擊面 則難以因應並行資料變更
  • 可能會變更 VMO 的快取性或其他屬性 壓縮器未定義行為時的平行快取使用方式。

這裡的提案是複製原始網頁,因為這是一個非常複雜的 可能的情況,複製可更快解決要求,避免 而不需要使用不同的同步處理機制複製作業正在 歸入 VMO 鎖定,但這與所有其他寫入時複製的複製作業相同 在 VMO 鎖定下,可以執行頁面複製的路徑。因為系統對於 單一壓縮時,任何特定 VMO 作業都能達成 最多一次的情境

解壓縮演算法

系統實作解壓縮作業,以利用現有的 PageRequest 系統。 已用於延遲分配,以及執行使用者呼叫器 要求。就像使用者呼叫器 VMO 的不存在頁面 VMO 頁面清單中的壓縮參照會觸發 類似的流程:

Take VMO lock
Observe page is compressed
Fill in the PageRequest
Drop VMO lock
Wait on the PageRequest
Retry operation

填入網頁要求時,我們必須儲存壓縮參照 以及 VMO 和偏移值這就需要擴增 現有的 PageRequest 結構

不同於使用者呼叫器網頁要求和壓縮, 等待系統直接解決要求,在這種情況下, 解壓縮。

解壓縮作業必須對多個嘗試存取 ,並提供優先順序沿用機制的方法:

Declare stack allocated OwnedWaitQueue
Take compressed storage lock
Validate compressed reference
if compressed page has wait queue then
    take thread_lock
    release compressed storage lock
    wait on referenced wait queue
else
    store reference to our allocated wait queue in compressed block
    release compressed storage lock
    decompress into new page
    take VMO lock
    update VMO book keeping
    release VMO lock
    take compressed storage lock
    take thread lock
    remove wait queue reference
    release compressed storage lock
    wake all threads on wait queue

這裡只會使用 thread_lock,因為這是要保留的鎖定 執行等待佇列作業,且沒有其他 正在使用 thread_lock

目標壓縮大小

因為解壓縮的成本與解壓縮的緣故,現在只值得儲存 壓縮過的網頁。其他情況 系統可能還會儲存未壓縮版本,可以節省解壓縮費用。

這個目標大小應該是可調整的選項,但目標 70% 是常見目標 和其他系統中。

如果壓縮嘗試超出目標範圍,就會視為 無法成功,且系統會依 「老化與追蹤」部分

零掃描頁面

基本上,壓縮時必須檢查來源中的所有位元組 時,他們有機會偵測並刪除重複的零網頁。這個 代表壓縮的替代結果,其回報 只是零個網頁,也不會將結果儲存在 壓縮儲存系統VMO 呼叫端可以改用 。

現成的壓縮演算法通常沒有辦法 表示輸入內容為零,因此要實現這一點,就必須採取下列任一做法:

  • 如要執行這項追蹤,請修改或建立導入作業。
  • 比較經過壓縮的結果與已知簽章。

第二個選項會運用壓縮演算法 確定性,且通常在 一個位元組先檢查大小再執行記憶體比較檢查, 價格也相當低廉

本提案不需進行初始壓縮實作即可 而且必須建構 API 和 VMO 邏輯才能支援任何網頁,但必須建構 API 和 VMO 邏輯才能加以支援。 最後應該替換現有的零網頁掃描器,以便改用 。

壓縮演算法

我們建議使用 LZ4 做為初始壓縮演算法。查看實驗功能 評估部分,但必須符合下列重要需求:

  • 較小的尺寸 (4KiB) 十分適合使用。
  • 在穩定後啟動期間,未執行 malloc 或同等功能 作業。
  • 可以平行解壓縮,沒有共用的可變動狀態。壓縮必須 多半能同時發生解壓縮作業
  • 雖然非必要,但系統支援多個平行壓縮。

LZ4 還有能取消壓縮的實用屬性 預先考慮受限的目標緩衝區空間

壓縮後的儲存空間

儲存壓縮後的頁面可在程式碼複雜度與執行之間取得平衡 可能零碎的時間 並增加記憶體用量初始 如何將固定數量的壓縮頁面封裝至策略中,在本例中為三 所選的單一儲存頁面

這項儲存空間策略的核心概念是,每個儲存空間頁面 會有左側、中間和右側儲存運算單元因此能達到 壓縮比例為 3:1。

實作過程相當簡單,包括:

  • 搜尋某個版位中,有部分已填滿的現有頁面。
  • 如果沒有合適的版位,請將版位放在新頁面的左側版位。

其中兩個小工具為:

  • 請根據頁面大小,將部分填寫完畢的頁面歸類到搜尋清單 ,透過 O(1) 搜尋服務提供近乎完美的行李服務。
  • 如果左側或右側版位較大,將無法使用中間版位 足夠的資料

這類策略的好處如下:

  • 導入簡單。
  • 無長尾效能的可預測作業。
  • 最糟的情況會降級,不再使用任何額外記憶體。

系統可能需要處理的一種病態行為 在未壓縮的情況下,可能會發生填孔及啟用 釋出儲存空間頁面只有在必要時 適時顯示

長期下來,它可以搖身一變為一般的堆積 研究室樣式配置器

如需瞭解一些初步結果,請參閱實驗功能評估一節。

會計和指標

雖然壓縮作業會在使用者未輸入內容的情況下執行 影響回報記憶體用量的方式此外,我們也要竊取 向使用者額外提供壓縮效能的資訊。

內容與承諾

現有的查詢介面會參照承諾的位元組和頁面來代表實際 則直接透過 VMO 分配記憶體來保存資料

這些現有的查詢如下:

  • ZX_INFO_TASK_STATS 會回報 mem_private_bytes 中的承諾記憶體, mem_shared_bytes
  • ZX_INFO_PROCESS_MAPS,其中對應的 VMO 為 committed_pages
  • ZX_INFO_PROCESS_VMOS / ZX_INFO_VMO,回報 committed_bytes
  • ZX_INFO_KMEM_STATS / ZX_INFO_KMEM_STATS_EXTENDED回報「vmo_bytes」 並計入修訂版本

除了內容位元組/網頁之外,我們也會加入額外的說明 。任何討論承諾記憶體的查詢 特別是指直接保存 VMO 內容的記憶體內容 而是核心為使用者保留的資料量,但不會有 具體說明方式也就是說,內容可直接存放在頁面中 因此,這些數據 也能計入 。

經過壓縮且大小為不明的內容 儲存空間大小嘗試屬性儲存空間中的個別壓縮頁面 儲存空間很複雜且不穩定,因為儲存空間大小取決於總容量 系統壓縮行為和產生的片段

雖然匿名 VMO 開始以 0 表示,但系統不會將其視為 核心內容如果使用者明確修訂 等網頁改寫成內容之後就算使用者退出 或將內容重設為 0,核心沒有義務注意到這一點, 可能會繼續視為正在追蹤的內容

針對移除和使用者呼叫工具,可從 系統不會將使用者呼叫器視為核心追蹤的內容。因此 從承諾和內容數量中扣除多少百分比

指標

如要瞭解壓縮的成效,無論是調整 / 開發還是 持續監控系統健康狀態,我們需要收集並提供指標。

這些指標應該要能解答壓縮方式的問題 以及對系統效能的影響。特別是 想知道以下事項:

  • 壓縮儲存空間比率。
  • 網頁的壓縮時間長度。
  • 系統會壓縮哪些類型的網頁,以及觸發哪些網頁。
  • 解壓縮延遲時間。
  • 執行壓縮和解壓縮作業所需的 CPU 作業時間。
  • 壓縮成功與失敗的比率。

API 變更

透過結構體演變和查詢版本管理來擴展:

  • zx_info_maps_mapping_t 包含 content_pages 欄位,
  • zx_info_vmo_t 包含 content_bytes 欄位,
  • ZX_INFO_TASK_RUNTIME,將page_fault_decompress_time回報為一小部分 page_fault 次。

需要為下列屬性進行版本管理的 zx_object_get_info 查詢:

  • ZX_INFO_PROCESS_MAPS
  • ZX_INFO_PROCESS_VMOS
  • ZX_INFO_VMO
  • ZX_INFO_TASK_RUNTIME

現有欄位 (例如 zx_info_vmo_tcommitted_bytes) 將會 更新註解和說明文件,清楚說明這些 都處於壓縮狀態

確切的內容會在疊代階段中尚未定案,但建議加上 要回報的 ZX_INFO_KMEM_STATS_COMPRESSION 項查詢:

struct zx_info_kmem_stats_compression {
    // Size in bytes of the content that is current being compressed.
    uint64_t uncompressed_content_bytes;

    // Size in bytes of all memory, including metadata, fragmentation and other
    // overheads, of the compressed memory area. Note that due to base book
    // keeping overhead this could be non-zero, even when
    // |uncompressed_content_bytes| is zero.
    uint64_t compressed_storage_bytes;

    // Size in bytes of any fragmentation in the compressed memory area.
    uint64_t compressed_fragmentation_bytes;

    // Total amount of time compression has spent on a CPU across all threads.
    // Compression may happen in parallel and so this can increase faster than
    // wall clock time.
    zx_duration_t compression_time;

    // Total amount of time decompression has spent on a CPU across all threads.
    // Decompression may happen in parallel and so this can increase faster than
    // wall clock time.
    zx_duration_t decompression_time;

    // Total number of times compression has been done on a page, regardless of
    // whether the compressed result was ultimately retained.
    uint64_t total_page_compression_attempts;

    // How many of the total compression attempts were considered failed and
    // were not stored. An example reason for failure would be a page not being
    // compressed sufficiently to be considered worth storing.
    uint64_t failed_page_compression_attempts;

    // Number of times pages have been decompressed.
    uint64_t total_page_decompressions;

    // Number of times a page was removed from storage without needing to be
    // decompressed. An example that would cause this is a VMO being destroyed.
    uint64_t compressed_page_evictions;

    // How many pages compressed due to the page being inactive, but without
    // there being memory pressure.
    uint64_t eager_page_compressions;

    // How many pages compressed due to general memory pressure.
    uint64_t memory_pressure_page_compressions;

    // How many pages compressed due to attempting to avoid OOM or near OOM
    // scenarios.
    uint64_t critical_memory_page_compressions;

    // The nanoseconds in the base unit of time for
    // |pages_decompressed_within_log_time|.
    uint64_t pages_decompressed_unit_ns;

    // How long pages spent compressed before being decompressed, grouped in log
    // buckets. Pages that got evicted, and hence were not decompressed, are not
    // counted here. Buckets are in |pages_decompressed_unit_ns| and round up
    // such that:
    // 0: Pages decompressed in <1 unit
    // 1: Pages decompressed between 1 and 2 units
    // 2: Pages decompressed between 2 and 4 units
    // ...
    // 7: Pages decompressed between 64 and 128 units
    // How many pages are held compressed for longer than 128 units can be
    // inferred by subtracting from |total_page_decompressions|.
    uint64_t pages_decompressed_within_log_time[8];
};

報表資訊壓縮的時間,意味著時間戳記必須 就會一併記錄下來。這應該不會產生 您將能瞭解 網頁正在快速壓縮中。

ZX_INFO_KMEM_STATS_EXTENDED Pager 位元組

ZX_INFO_KMEM_STATS_EXTENDED 查詢含有專門用來處理 (以頁面伺服器支援的 VMO 為準)具體欄位如下:

    // The amount of memory committed to pager-backed VMOs.
    uint64_t vmo_pager_total_bytes;

    // The amount of memory committed to pager-backed VMOs, that has been most
    // recently accessed, and would not be eligible for eviction by the kernel
    // under memory pressure.
    uint64_t vmo_pager_newest_bytes;

    // The amount of memory committed to pager-backed VMOs, that has been least
    // recently accessed, and would be the first to be evicted by the kernel
    // under memory pressure.
    uint64_t vmo_pager_oldest_bytes;

提議的實作方式會統合受呼叫器支援且匿名的 VMO 頁面 這麼一來,這些資訊就變得不切實際。 因此,提案重新定義,為所有可分頁 / 可回收的提案 不只是可收回的使用者呼叫器 VMO 否則,系統會保留最新和最舊定義。

雖然重新宣告壓縮記憶體無法直接轉譯成 PMM 可用記憶體增加量,這些查詢的目的並非 可收回的 PMM 記憶體確切容量而是提供深入分析 方便您掌握各年齡層的記憶體相對分佈情形 在裝置 OOM 上,oldest_bytes 等驗證作業會停止運作且接近零。 依此類推

擁有多個欄位供使用者呼叫器使用,可收回的記憶體與可壓縮 匿名記憶體也是有問題的一定會有 因此非常有價值地區分這些屬性 因此,我預期這 2 月份的匯總報表

停用壓縮 / 易受延遲的 VMO

針對易受延遲影響的應用程式,必須該採用相應機制, 停用 VMO 的壓縮功能,無論解壓縮延遲時間有多低 可能會讓人無法容忍

避免重述和其他類型的核心活動,以免增加 記憶體存取延遲時間目前已經著手解決。阿斯 我們不會在這裡提出任何設計建議,但這項工作是 。

擴充功能

除了最初的提案設計,還有一些探索和改善項目 能做到這一點雖然這類做法通常屬於導入作業 的目的,是激勵他們長期適切地採用解決方案 設計。改善相關技術時建議採行的改善措施,最好在 包括:

  • 移除不同的零重複頁面刪除,改用壓縮。

除此之外,您也可以嘗試其他可能有助於提供實用效益的想法:

  • 請先壓縮支援 Pager 的記憶體,再予以移除。
  • 支援在不捨棄未壓縮頁面的情況下執行壓縮,直到 記憶體壓力
  • 步行其他的舊網頁清單 並積極壓縮網頁,而不只是 LRU 佇列。

還可以進一步微調儲存空間和壓縮演算法 或是提供不同產品選項這些 可能會需要個別的 RFC,端視侵入或不同之處而定。

實作

導入程序將在本文概述的多個階段執行。

一般施工架

常見的 VM 系統有所變更,以支援對匿名的老化與追蹤 會先導入網頁這些回應沒有行為或 API 變更,但 代表風險最高的變更,先這麼做可以:

  • 在樹狀結構中做出變更,並經過最長時間測試
  • 能夠測量候選壓縮集區 (即舊的匿名模型) 網頁)。

核心實作

完成主要核心實作的常見變更之後 都位於功能旗標後方這樣一來,您就能透過 先確保其穩定,再公開其 可透過任何 API 存在

API 革新

針對指標和會計作業執行 API 演變和結構體遷移 並輸入變更內容由於核心實作是在樹狀結構中,因此 API 變更可 掛鉤,不過壓縮作業仍會保留在功能旗標後方 一般使用者將不會看到功能方面的異動。

整合、擴充功能與調整

完成導入測試後,就能記錄可評估的指標 不同產品之間能找出任何問題,讓擴充功能易於調整 決定要執行的內容

這項測試的結果將決定:

  • 壓縮功能預設為啟用,因此部分產品會停用壓縮功能,或是
  • 壓縮功能預設為關閉,部分產品會啟用。

擴充功能與調整

您現在可以推出延伸設計的部分內容,並進行一般實作。 的開發套件

成效

必須評估成效的兩個層面。

一般負擔

即使已停用壓縮功能,一般 VM 程式碼也會有基本異動 這些做法也會影響成效

在匿名網頁中加入反向連結,可有效評估 會產生所有 VMO 本機副本建立和刪除事件的負擔這些作業 而非著重效能的關鍵路徑,因為這類路徑通常是在初始化期間 相關步驟,不過請留意 產品對產品的影響

其他 VMO 路徑會產生小額負擔,以便維護反向連結及更新 但應用於雜訊,且不會產生實際的影響。

這些路徑會受現有的 VMO 微型基準測試 主要驗證工具

壓縮效能

壓縮指的是 CPU 對記憶體的取捨 成效只能根據產品本身及其需求評估。

否則建議使用的指標 API 壓縮會產生大量成本 然後便可使用壓縮可微調項目 可根據節省的記憶體容量 控製成本

安全性考量

時間管道

雖然經過壓縮的網頁可能使用相同的儲存空間,但流程 存取此儲存空間的行為定義為沒有遞移依附元件 進而產生可評估管道的 VMO這是刻意設計的作業 避免遭受類似攻擊 記憶體簡化攻擊

儘管缺乏遞移依附元件,還是有時間管道 如果攻擊者可以控制共置於同一位置的資料 就能取得這些資訊這些資料可能經過壓縮 成功或失敗,讓攻擊者藉由學習 洩漏祕密然而,這類攻擊真的可行嗎? 這是否和阻止壓縮延遲的機制相同 也可能會使用敏感任務

系統行為管道

整體系統記憶體用量可以直接透過以下方式查詢: ZX_INFO_KMEM_STATS_COMPRESSION 或藉由查詢例如 VMO 並觀察內容和已修訂的位元組是否有差異。 您也可以查詢 ZX_INFO_KMEM_STATS_COMPRESSION 中的其他統計資料。

從而提供有關整體系統行為的間接資訊。 然而,據以判斷 VMO 的頁面是否 只要使用 YAML 或 BERT 模型 上傳資料集之後,您可以運用 AutoML 自動完成部分資料準備工作

LZ4

雖然 LZ4 程式庫的檔案大小和 LoC 指標很少 以低階樣式的 C 語言編寫而成的小型程式碼,因此可能會出現錯誤。 就需要混合使用下列項目:

  • 安全性審查,確認整體合適度。
  • 額外的強化和測試。
  • 系統可能重新編寫有問題的片段。

同時強化和重新編寫可能會導致部分或全部 實作更安全的表示法,例如 Rust 或 WUFFS

測試

與成效類似,測試有兩種維度。

VM 正確性

一般 VM 變更的技術正確性,以及 壓縮特定變更,系統將使用 unittests 和 整合測試

適用於無論壓縮大小,都會生效的一般 VM 變更 是否在核心單元測試或其他核心測試中,將新增為 或適當。

使用 QEMU 執行器的整合測試,會用來執行 壓縮功能

系統行為

雖然壓縮的過程不自由,但不應對任何行為造成負面影響 對於產品的擁有者來說,這是至關重要的一點這些行為 但更像是跳過音訊、誇大的輾轉現象 導致使用者體驗不佳

這包含手動測試產品、使用鎖定等工具 追蹤內容,並與產品測試團隊和產品合作 負責評估工作的人員

說明文件

系統會記錄 zx_object_get_info 查詢的新增和變更 以及其他 cmdline 選項

缺點、替代方案和未知

不明和疊代

必須等到提案產生後,才能充分瞭解這項提案的確切優勢和費用 實際使用產品並進行評估雖然這個提案 旨在向所有參與者提供特定且合理的初步提案 演算法和結構,可以確定會隨著 用於追蹤實際的使用資料

缺點

本提案的主要缺點是導入 VM 系統的複雜性 與核心部分相同雖然壓縮的任何效能面向都可以 應該停用該功能所避免的機制 需要變更現有的壓縮機制 共用基礎架構因此,這個階段的複雜性和風險 與進行壓縮相關 (即使未使用)

使用者呼叫器壓縮替代方案

相較於在核心中執行壓縮和解壓縮, 透過使用者呼叫器機制,將外包給外包給使用者空間。從許多層面來看 與 Linux 上的 ZRAM 類似,前者是由使用者空間檔案系統實作 驅動程式。但很抱歉,這也有許多缺點。

優點

想在使用者空間中壓縮內容,主要有兩個主要原因:

  1. 從核心中移除複雜的壓縮和解壓縮程式碼。
  2. 讓使用者在導入過程中享有更多彈性。

可惜的是 (1) 並非完全正確,因為除了單獨的文本例項以外 會為每個安全性網域建立 (但稍後會判定) 這項使用者空間程序能夠查看應用程式中每個程序的匿名記憶體 以及系統這將成為非常值得信任的,因為任何入侵都可能 查看及編輯系統中的所有使用者記憶體。因此 與核心相比,這裡的壓縮和解壓縮程式碼都不會較低。

提供彈性實作是值得的,不過 例如設定機制,將特定記憶體的 特定壓縮器的匿名 VMO因此您可能不需要 但也可以採用交換或任何其他策略

缺點

使用者空間壓縮的主要缺點,就是它提供的限制 與核心部分相同能夠以樂觀方式壓縮網頁及解壓縮網頁 (可能在不捨棄未壓縮的項目的情況下) 會為核心提供 提供絕佳的實作彈性所有這類配置都能透過 但這卻成為更複雜的分散式系統問題 會需要非常謹慎的 API 和並行推理

雖然 Zircon 是元件系統,切換使用者非常便宜 太空工作,需要向下呼叫使用者空間處理程序才能解壓縮 4KiB 網頁,會使延遲時間和成本大幅增加。可以鼓勵延遲 壓縮到網頁變長之前,可有效節省記憶體。適用對象 如果現有使用者呼叫器錯誤,系統會假設 正在查詢儲存空間,因此剔除作業已無法延遲清除

即使使用者空間會處理壓縮和解壓縮作業,所有核心 您還是需要調整網頁年齡追蹤及壓縮觸發 完成。因此,所有可調整項目和指標仍需要存在於核心中。 此外,VM 系統目前無法將使用者呼叫器連結至 會需要進一步變更及重新設計 VM 有些人會將 Cloud Storage 視為檔案系統 但實際上不是

核心程式碼解譯器

我們支援使用者提供的是固定的壓縮演算法 以及透過使用者提供的核心程式碼 也就是 Linux eBPF這樣一來 靈活導入,不影響 讓使用者停止運作

雖然不需要明確的模式轉換,但核心仍需要 就成效特性而言 因此 您在鎖定這些網路後 叫用提供的程式碼。

這種方法的主要缺點是,核心中的 VM 足以產生可接受的壓縮效能。 確實相當複雜且大幅提高 需要的信任運算基礎

未來

我們希望未來能以替換方式,讓匿名 VMO 獲得支援 如果 30 天內讀取資料不到一次 建議使用 Coldline Storage這項操作絕對需要在使用者空間中導入 分頁機制此時,這種替換實作可以壓縮 而不單只是替換不過,由於 我發現這與核心壓縮並同存在,不會取代 基礎架構

會計替代方案

提案目前建議重新定義內容位元組/網頁 以配合現有承諾數量在不變更計算項目的情況下 另有其他命名選項,例如:

  • 居民和承諾
  • 居民和內容

每項工作都需要變更目前使用承諾的所有使用方式,因此 規模變更,並增加兩個 API 版本的連續性。

ZX_INFO_KMEM_STATS_EXTENDED Pager 位元組替代方案

雖然提議的實作方式會統一建立網頁程式並匿名化 佇列使其計數難以分隔, 系統可能會分開計算計數。

這種替代執行方式會分別針對 可回收佇列的一部分儲存在page_queue_priv vm_page_t 可用於區分需要更新哪個計數 在佇列之間移動頁面。

這種方法的缺點是:

  • 增加 page_queue_priv 的使用複雜度。經過包裝後 欄位而不是計數器,而且所有讀取和寫入作業都需要保留或遮蓋 額外
  • 存取採集型取景方式:持有拱門鎖的拱門鎖,因此費用 隨著佇列資訊需要解碼、正確計數而增加 已更新。
  • 使用多個計數欄位,而且增加複雜度,使這些欄位保持一致。

如提案中所述,我認為網頁伺服器位元組欄位實際上是哪些欄位 這兩者的計算值,因為分隔計數不見得很小 增加實作複雜性和執行階段成本

實驗性評估

為了提議採用 LZ4 壓縮演算法和壓縮儲存空間 策略,是一種實驗用的壓縮版本 遷移至:

  • 收集一組已停用的匿名網頁樣本 壓縮後的版本。
  • 對這個資料集執行不同的壓縮演算法。

主要目的是利用以下工具評估不同的壓縮演算法:

  • 實際產品提供的真實輸入資料。
  • 位於與核心正確相符的受限執行環境中。

當核心程式碼在不支援的情況下執行時,第二點就顯得格外重要 代表 FPU/SSE/AVX 等等

使用 64MiB 輸入資料集執行評估,每個 4KiB 頁碼 然後個別提供給壓縮機,就像在實際運作時一樣。 結果資料會以下列方式解讀:

  • 壓縮成功表示壓縮到原始大小的 70% 以上。
  • 壓縮時間適用於所有網頁,包括最終 還是以壓縮方式儲存檔案這與真實使用情形相符 預測壓縮是否成功
  • 只有成功的網頁才會計算解壓縮時間 壓縮後的版本。
  • 總大小計算的是每個網頁所需的儲存空間,因此 壓縮後的大小會增加到計數中,且 壓縮失敗的網頁會計為 4KiB。

這種計算樣式的根本原因在於 盡可能減少記憶體用量有時可快速執行的壓縮演算法 非常擅長壓縮網頁,否則耗費大量 CPU 而無法執行 壓縮後既不會節省太多記憶體 又會耗用大量的 CPU

NUC 7

演算法 壓縮 (MiB/秒) 解壓縮 (MiB/秒) 解壓縮最嚴重的延遲時間 (ns) 總大小 (MiB)
zstd(-7) 752.1470396 1446.748532 9302.3125 18.61393929
米尼索 1212.400326 2135.49407 6817.839844 16.16410065
LZ4(1) 1389.675715 2920.094092 6355.849609 17.21983242
lz4(11) 1801.55426 3136.318174 5255.708984 19.92521095 年
WKdm 1986.560443 3119.523406 3095.283203 21.98047638

ARM A53

演算法 壓縮 (MiB/秒) 解壓縮 (MiB/秒) 解壓縮最嚴重的延遲時間 (ns) 總大小 (MiB)
zstd(-7) 189.3189527 486.6744277 29856.93359 18.61393929
米尼索 317.4546381 528.877112 15633.99219 美元 16.16410065
LZ4(1) 294.5410547 1127.360347 12683.55273 17.21983242
lz4(11) 378.2672263 1247.749072 人 12452.67676 19.92521095 年
WKdm 337.6087322 471.9796684 14254.39453 21.98047638

ARM A73

演算法 壓縮 (MiB/秒) 解壓縮 (MiB/秒) 解壓縮最嚴重的延遲時間 (ns) 總大小 (MiB)
zstd(-7) 284.3621221 623.15235 20958.90332 18.61393929
米尼索 487.4546545 747.9218419 美元 16784.83105 16.16410065
LZ4(1) 441.5927551 1159.839867 10007.28418 17.21983242
lz4(11) 573.7741984 1240.964187 9987.875 19.92521095 年
WKdm 639.5418085 597.6976995 13867.47266 21.98047638

壓縮後的儲存空間

系統是透過同一個 64MiB 測試資料集評估提議的壓縮後資料集 以及儲存空間系統本例是以兩種模式評估,也就是兩頁系統 左邊和正確的插槽 還有建議的三個插槽系統 此連結旨在嘗試量化其複雜性的優點, 中間的空格,真的很簡單

LZ4 是提議的壓縮演算法,可用來產生 加速因數設為 11也就是說 針對 16384 輸入頁面,12510 產生的資料必須儲存 3874 未壓縮。

吃角子老虎 儲存頁面 總 MiB 省下的金額 (MiB) 壓縮率
2 個插槽 6255 39.5 24.4 1.62
三個插槽 4276 31.8 32.1 2 月 1 日

請注意,6255 剛好是 12510 的一半,表示有好友 適用的 30 個像素 LZ4 輸入,這是這項儲存空間策略的最佳結果。

既有藝術品和參考資料

所有主流現代作業系統 (Windows、MacOS、Linux 和 Linux) 這類衍生工具 (例如 CastOS 等) 支援將記憶體壓縮,做為替代 做為磁碟交換的輔助

三頁式儲存策略是以 Linux zbud 和 z3fold 記憶體為基礎 以及管理系統