HRT:使用Huge Pages进行低延迟优化
量化投資與機器學習微信公眾號,是業內垂直于量化投資、對沖基金、Fintech、人工智能、大數據等領域的主流自媒體。公眾號擁有來自公募、私募、券商、期貨、銀行、保險、高校等行業30W+關注者,榮獲2021年度AMMA優秀品牌力、優秀洞察力大獎,連續2年被騰訊云+社區評選為“年度最佳作者”。
延遲通常是算法交易中的一個關鍵因素。在HRT,我們一直努力在最小化交易棧的延遲上。低延遲優化可能是晦澀難懂的,但幸運的是,有許多非常好的指南和文檔可以開始使用。
有一個不會經常深入討論但非常重要的方面是大內存頁(Hugepages)和轉譯后備緩沖器(Translation Lookaside Buffer,TLB)的作用。在本系列文章中,我們將解釋它們是什么,為什么它們重要,以及如何使用它們。我們將關注運行在64位X86硬件上的 Linux 操作系統,但是大多數觀點也適用于其他體系結構。
這一系列的文章是相對技術性的,需要對操作系統概念(如內存管理)以及一些硬件細節(如 CPU 緩存)有一些高層次的理解。在第一篇文章中,我們將解釋Hugepages的好處。在第二篇文章中,我們將解釋如何在生產環境中使用它們。
內存管理101
硬件和操作系統以塊的形式處理內存。這些小塊叫做頁面(pages)。例如,當操作系統分配或交換內存時,內存是以頁為單位進行的。
在64位x86體系結構中,默認的頁面大小為4 KB (KiB)。但是 x86 64位 CPU 還支持其他兩種頁面大小,Linux稱之為Hugepages: 2MiB 和1GiB(1GiB頁面也被稱為巨型頁面)。為了簡單起見,本系列文章主要關注2MiB 頁面。1GiB 頁面也很有幫助,但是它們太大了,所以往往有更專門的用例。
內存地址映射快速入門
當常規程序運行時,它們使用虛擬地址訪問內存。這些地址通常只在當前進程中有效。硬件和操作系統協作將這些映射到物理內存(RAM)中的實際物理地址。這種翻譯是每頁完成的。
由于程序只能看到虛擬地址,因此在每次訪問內存時,硬件必須將程序可見的虛擬地址轉換為物理 RAM 地址(如果虛擬地址確實由物理內存支持的話)。內存訪問意味著從處理器加載或存儲數據或指令,而不管它們是否被緩存。
操作系統將這些轉換存儲在一個稱為頁表的數據結構中,硬件也能理解這種數據結構。對于每個由真實內存支持的虛擬頁,頁表中的一個條目包含相應的物理地址。對于機器上運行的每個進程,頁表通常是唯一的。
為什么訪問頁表可能會顯著增加延遲?
除非程序的分配器和/或操作系統設置為使用Hugepages,否則內存將由4KiB 頁面支持。X86上的頁表使用多個層次結構級別。因此,在頁表中查找4 KiB 頁的物理地址至少需要3個相關的內存負載。
緩存將用于嘗試實現這些功能(類似于任何常規的內存訪問)。但是讓我們假設所有這些加載都是未緩存的,并且需要來自內存。使用70ns 作為內存延遲,我們的內存訪問已經有70 * 3 = 210納秒的延遲ーー而且我們甚至還沒有嘗試獲取數據!
進入轉譯后備緩沖器
CPU 設計人員非常清楚這個問題,并提出了一系列優化來減少地址轉換的延遲。我們在這篇文章中關注的具體優化是轉譯后備緩沖器(TLB)。
TLB 是地址轉換信息的硬件緩存。它包含頁表中許多最近訪問的條目的最新副本(最好是當前進程的頁表中的所有條目)。正如訪問 CPU 緩存比訪問內存快一樣,在 TLB 中查找條目比在頁面表中搜索要快得多。當 CPU 找到它在 TLB 中尋找的轉換時,它被稱為 TLB Hit。如果沒有,這是一個 TLB Miss。
但是,就像常規的 CPU 緩存一樣,TLB 的大小是有限的。對于許多需要大量內存的進程,整個頁表的信息將放不進 TLB。
TLB 有多大?
一個不錯的經驗法則是,最近的服務器 x86 CPU 的 TLB 為每個核心大約1500-2000個條目(例如,cpuid 可以用來為 CPU 顯示這些信息)。因此,對于使用4KiB 頁面的進程,TLB 可以緩存翻譯,以覆蓋2000(TLB 中的條目數)* 4KiB(頁面大小)字節,即8MiB 值的內存。這比許多程序的工作集小得多。甚至 CPU 緩存通常也要大得多!
現在,假設我們使用的是Hugepagesー我們的 TLB 可以包含2000 * 2MiB = ~ 4GiB 的轉換信息。這樣好多了。
Hugepages的其他好處
一個Hugepage占用的內存是4KiB 頁面的512倍。這意味著對于相同的工作集,頁表中的條目數也比使用常規頁時少512倍。這不僅大大減少了頁表使用的內存量,而且使表本身更容易緩存。
此外,2MiB 的頁表格式比普通頁簡單,因此查找需要更少的內存訪問。因此,即使一個由Hugepages支持的程序在地址轉換時遇到了TLB miss,頁表查找也會比普通頁面快得多(甚至是顯著地快)。
測試與對比
如果沒有一個完全人為的基準,任何關于優化的帖子都是不完整的。我們編寫了一個簡單的程序,分配一個32GiB 的雙精度數字陣列。然后從這個數組中添加1.3億個隨機雙精度數(完整的源代碼在這里可以找到)。在第一次運行時,程序在數組中生成一個隨機的索引列表,然后將它們存儲在一個文件中。隨后的運行將讀取該文件,因此在每次運行期間內存訪問將是相同的。
我們在一臺空閑的 Intel Alder Lake 機器上運行這個程序。當使用Hugepages時,程序初始化部分的基準時間要快40% 。數組是線性初始化的,這是硬件的最佳情況,因此加速效果不會很明顯。但是,當進行隨機訪問以添加雙精度數時,運行時會減少4.5倍。請注意,隨著程序中的小更改或使用不同的編譯器,運行的秒數可能會有很大的不同。然而,Hugepages的性能改進仍然十分明顯。
什么時候不應該使用Hugepages
Hugepages 一種優化。就像任何其他優化一樣,它們可能適用于工作負載,也可能不適用于工作負載。基準管理對于確定是否值得投入時間來建立它們非常重要。在本系列的第二篇文章中,我們將詳細介紹如何使用它們,并列出一些實質性的警告。
結論
在每次訪問代碼或數據的內存時,硬件將虛擬地址轉換為物理地址。使用Hugepages可以顯著地加速這種映射。Hugepages還允許 TLB 覆蓋大量內存。理想情況下,我們希望我們的整個工作集可由 TLB 映射,而不需要轉到頁表。這減少了內存訪問的延遲,也釋放了 CPU 緩存中的一些空間(不再需要包含那么多緩存頁表條目)。
總結
以上是生活随笔為你收集整理的HRT:使用Huge Pages进行低延迟优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器IIS6/IIS7、Nginx、A
- 下一篇: 二十年后的家乡(小学习作)