在NUMA架構(尤其是ARM執行個體)中,不同NUMA節點具有各自的本地記憶體,當一個NUMA節點上的程式或進程需要訪問其他NUMA節點的程式碼片段時,就會引入額外的延遲和效能開銷。通過代碼多副本功能,可以將遠程節點的程式碼片段複製到本地節點,避免了跨節點訪問,從而解決NUMA架構中因跨節點訪問帶來的效能延遲問題。
背景資訊
使用限制
僅以下執行個體規格和鏡像支援代碼多副本功能。
執行個體規格:ECS Bare Metal Instance規格類型系列群。更多資訊,請參見ECS Bare Metal Instance。
鏡像:核心版本是
5.10.112-11
及以上的Alibaba Cloud Linux 3鏡像。說明您可以通過
uname -r
命令查詢鏡像的核心版本。
配置開關
代碼多副本提供了全域開關和memcg開關,只有當兩個開關同時開啟時,核心系統內的進程才能使用代碼多副本功能。
配置開關 | 說明 |
/sys/kernel/mm/duptext/enabled | 全域開關用於設定當前核心系統是否啟用代碼多副本功能。取值範圍:0~1,預設值為0。
|
/sys/fs/cgroup/memory/<memcg目錄名稱>/memory.allow_duptext | 在全域開關開啟的前提下,memcg開關用於設定各memcg中的進程是否啟用代碼多副本功能。取值範圍:0~1,預設值為0。
|
除了上述特性開關之外,您還可以通過以下方式查看副頁的統計資料。
通過
/proc/vmstat
中的nr_duptext
欄位或者/proc/meminfo
中的DupText
欄位查看整機的副頁統計資料。nr_duptext
表示在核心中標記為duptext的副頁數量。DupText
表示使用了多少記憶體來儲存duptext相關的資料,單位為KB。通常1個記憶體頁的大小是4 KB。
通過
/proc/pid/smaps
檔案可以查看對應進程的副頁統計資料。
使用代碼多副本功能
本樣本通過在一台具有兩個NUMA節點的ECS執行個體上編譯並執行一個測試程式test.c為例,示範代碼多副本功能的用法。
遠程登入ECS執行個體。
具體操作,請參見通過密碼或密鑰認證登入Linux執行個體。
(可選)運行以下命令,查看ECS執行個體的NUMA節點資訊。
numactl -H
說明如果您沒有安裝
numactl
,可執行sudo yum install numactl
命令進行安裝。如下圖所示,表示該執行個體有2個NUMA節點(node 0和node 1)。
運行以下命令,編譯測試程式並產生可執行檔。
本樣本假設在node 1上編譯test.c的原始碼檔案,並在node 1上產生test檔案的Page Cache。
numactl -N 1 -m 1 gcc test.c -o test
運行以下命令,開啟代碼多副本功能的全域開關。
sudo sh -c 'echo 1 > /sys/kernel/mm/duptext/enabled'
運行以下命令,建立一個memcg目錄並開啟memcg的多副本功能開關。
sudo mkdir /sys/fs/cgroup/memory/test sudo sh -c 'echo 1 > /sys/fs/cgroup/memory/test/memory.allow_duptext'
運行以下命令,通過代碼多副本功能避免跨節點訪問。
本樣本假設使用cgexec和numactl來運行可執行檔test,同時將進程綁定到node 0上。此時會在node 0上建立test相關程式碼片段的副本,即直接存取的是node 0上的副本,避免了跨節點訪問。
sudo cgexec -g "memory:test" numactl -N 0 -m 0 ./test
說明如果您沒有安裝
cgexec
,可執行sudo yum install -y libcgroup-tools
命令進行安裝。運行以下命令,查看test程式的副頁統計資料。
sudo cat /proc/$(pidof test)/smaps
如下圖所示,展示了test的副頁統計資訊,表示在node 0上已經成功產生了test的副本。
說明您也可以分別運行以下命令,查看整機的副頁統計資料。
cat /proc/vmstat | grep -i duptext cat /proc/meminfo | grep -i duptext
關閉代碼多副本功能
後續您可以根據需要關閉代碼多副本功能。關閉多副本功能的同時,核心會自動清除整機上的所有副頁。
遠程登入ECS執行個體。
具體操作,請參見通過密碼或密鑰認證登入Linux執行個體。
運行以下命令,關閉代碼多副本功能。
sudo sh -c 'echo 0 > /sys/kernel/mm/duptext/enabled'
運行以下命令,驗證是否關閉代碼多副本功能。
cat /proc/vmstat | grep -i duptext cat /proc/meminfo | grep -i duptext
如下圖所示,整機上的所有副頁已經被清除,表示已經關閉代碼多副本功能。