在NUMA架构(尤其是ARM实例)中,不同NUMA节点具有各自的本地内存,当一个NUMA节点上的程序或进程需要访问其他NUMA节点的代码段时,就会引入额外的延迟和性能开销。通过代码多副本功能,可以将远程节点的代码段复制到本地节点,避免了跨节点访问,从而解决NUMA架构中因跨节点访问带来的性能延迟问题。
背景信息
使用限制
仅以下实例规格和镜像支持代码多副本功能。
实例规格:弹性裸金属服务器规格族群。更多信息,请参见弹性裸金属服务器。
镜像:内核版本是
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
如下图所示,整机上的所有副页已经被清除,表示已经关闭代码多副本功能。