操作系统设置#

本章提供有关操作系统设置的信息。

页面大小#

Grace 支持 64K 和 4K Linux 内核页面大小。要使用适合您业务需求的页面大小配置您的 Linux 内核,请在内核编译期间更改以下 kconfig 设置

  • 4K 页面大小: CONFIG_ARM64_4K_PAGES=y

  • 64K 页面大小: CONFIG_ARM64_64K_PAGES=y

64K 页面大小可以使分配大量内存的应用程序受益,因为页面错误会更少,TLB 命中率更高,效率更高。

注意

建议的页面大小默认值为 64K。

巨页#

巨页可能对分配大块内存的应用程序有利,主要好处是 TLB 未命中次数更少。

您可以通过以下方式在 Grace 系统上使用巨页

  • 透明巨页 (THP)

    • 对应用程序透明。

    • 主要是自动的,只有少数可用的内核调优参数。

    • 当使用推荐的 64 KB 页面大小时,THP 页面对于大多数应用程序来说目前都太大而无法实际使用(有关更多信息,请参阅透明巨页)。

  • Hugetlbfs

    • 不会受到碎片问题或分配延迟的影响,因为巨页是预先分配且不可分割的。

    • 需要修改应用程序。

    • 需要系统管理员设置。

透明巨页#

透明巨页 (THP) 对应用程序完全透明,应用程序无需更改源代码即可获得巨页的好处(有关更多信息,请参阅透明巨页支持)。截至内核版本 6.5,当配置 64 KB 系统页面大小时,仅支持 512 MB THP 页面。如果 512 MB THP 对于您的应用程序来说太大,请考虑使用 hugetlbfs,如Hugetlbfs中所述。

有关 THP 的更多信息,请参阅透明巨页支持

注意

默认巨页大小与内核页面大小有关(有关更多信息,请参阅ARM64 上的 HugeTLBpage)。

主动压缩#

主动压缩通过在后台抢先执行工作来减少巨页的分配延迟,不会改变获取巨页的概率,但会改变您获取巨页的速度。

  • 在没有压缩的情况下,内核将返回巨页,直到用完为止。应用程序将遇到性能悬崖,因为内核将对内存进行碎片整理,而主动压缩会平滑此过程。

  • 使用压缩时,当应用程序达到内存碎片阈值时,内核开始在后台对内存页进行碎片整理,这可以防止您耗尽巨页并遇到性能悬崖。

主动压缩公开了一个可调参数 /proc/sys/vm/compaction_proactiveness,它接受 [0, 100] 范围内的值,默认值为 20。此可调参数确定内核应在后台多积极地压缩内存,设置激进的值可能会导致地址转换延迟增加。默认值 20 是合理的,仅应根据性能数据进行更改。为了限制主动压缩的开销,您可以使用按需压缩方法,该方法仅在设置 CONFIG_COMPACTION 后可用。当 1 写入 /proc/sys/vm/compact_memory 文件时,所有区域都会被压缩,并且空闲内存在可能的情况下以连续块的形式提供。这可能很重要,例如,在分配巨页时,因为它也会根据需要直接压缩内存。有关更多信息,请参阅/proc/sys/vm/ 的文档

Hugetlbfs#

通过使用 hugetlbfs,可以预先分配 hugetlb 页面池,应用程序可以使用这些池中的巨页。但是,这需要更改应用程序。您可以指定系统保留的最小巨页数、池可以增长到多大,以及配置 malloc 以将 hugetlbfs 用于应用程序。我们强烈建议您使用 hugetlbfs 测试您的应用程序,如果它适用于您的应用程序,请使用您的应用程序。在启动时保留巨页池的好处是,在启动时,内存不会碎片化,因此更有可能组装请求的巨页数。有关更多信息,请参阅HugeTLB 页面

配置 Linux Perf#

有关更多信息,请参阅配置 Perf

性能调速器#

您可以使用 cpupower 命令设置 CPU 调速器。例如,要将 CPU 调速器设置为 Performance,请运行以下命令

sudo cpupower frequency-set -g performance

注意

在某些发行版(如 Ubuntu)上,cpufrequtils 软件包提供了一个 cpufrequtils 服务,该服务可能会在系统启动时将 CPU 调速器更改为 ondemand。为了避免这种行为,用户可以通过运行 sudo systemctl disable cpufrequtils 命令禁用此服务。

Init on Alloc#

CONFIG_INIT_ON_ALLOC_DEFAULT_ON 内核配置选项控制内核是否默认用零填充新分配的页面和堆对象。您可以使用 init_on_alloc=[0|1] 内核参数覆盖此设置。

在 Grace Hopper 等一致性系统上,GPU 内存作为系统内存公开,这可能会对 cudaMalloc() 操作造成严重的性能影响。

注意

Grace Hopper 上建议的默认值是 init_on_alloc=0 参数。

并非所有发行版都会在其内核上设置 CONFIG_INIT_ON_ALLOC_DEFAULT_ON 配置。例如,SUSE 和 RHEL 内核目前未设置此选项,但 Ubuntu -generic 内核设置了此选项。系统上 init_on_alloc kernel 配置选项的当前值可以按如下方式打印

grep init_on_alloc /proc/cmdline

这是输出

BOOT_IMAGE=/boot/vmlinuz-6.2.0-1010-nvidia-64k
root=UUID=7123054d-9b18-4c3d-8844-c538c751b59a ro
rd.driver.blacklist=nouveau nouveau.modeset=0 earlycon
module_blacklist=nouveau acpi_power_meter.force_cap_on=y
numa_balancing=disable init_on_alloc=0 preempt=none

输入-输出内存管理单元直通#

输入-输出内存管理单元 (IOMMU) 是一种硬件组件,它执行从 I/O 设备虚拟地址(也称为 I/O 虚拟地址 (IOVA))到物理地址的地址转换。不同的平台有不同的 IOMMU,例如 PCI Express 显卡使用的 Intel IOMMU 图形地址重映射表 (GART) 和 ARM 平台使用的系统内存管理单元 (SMMU)。Linux 提供了 iommu.passthrough 模式,您可以配置 DMA 以使用(或不使用)IOMMU 来访问内存以进行寻址。此版本要求启用 SMMU 直通。未来的内核版本将更改该指南,但目前,不要在直通模式下使用 SMMU 运行 CUDA 程序。在内核命令行上将 iommu.passthrough 设置为 1 会绕过 DMA 的 IOMMU 转换,将其设置为 0 会对 DMA 使用 IOMMU 转换。此值需要在部署时(在内核配置中)或通过编辑相应的 grub 配置文件来设置。要使更改生效,您需要重新启动系统。

要添加内核参数,请完成适用于您的发行版的步骤

Ubuntu

  1. 使用以下内容创建 /etc/default/grub.d/iommu_passthrough.cfg 文件

GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX iommu.passthrough=0"
  1. 运行以下命令

sudo update-grub
sudo reboot

RedHat

  1. 运行以下命令

    sudo grubby --update-kernel=ALL --args="iommu.passthrough=0"
    sudo reboot
    

SUSE

  1. 编辑 /etc/default/grub 文件。

  2. 在包含 GRUB_CMDLINE_LINUX 字符串的行上,附加 iommu.passthrough=0 参数,并运行以下命令

    sudo update-bootloader --refresh
    sudo reboot
    

自动 NUMA 调度和平衡#

在 Grace Hopper 系统上,我们建议您不要使用 Linux 内核的自动 NUMA 调度和平衡 (AutoNUMA) 功能。这是因为 AutoNUMA 引入了额外的页面错误,这会显着降低 GPU 密集型应用程序的性能。

  • 要查看 AutoNUMA 的状态,请使用 cat /proc/sys/kernel/numa_balancing

  • 如果输出为 1,则 启用 AutoNUMA;如果为 0,则 禁用 AutoNUMA。

  • 要在会话中禁用 AutoNUMA,请使用 echo 0 > /proc/sys/kernel/numa_balancing

  • 要永久禁用 AutoNUMA,请使用 echo "kernel.numa_balancing = 0" >> /etc/sysctl.conf

交换文件大小#

本节适用于 Grace Hopper 系统。

如果应用程序分配了足够大的 CPU 内存部分,则内核可能会决定将某些页面(可能来自第三方应用程序)从 CPU 内存迁移到 GPU 内存。目前,此内存只能通过交换文件回收。我们建议您为这些场景准备足够大的交换文件。

注意

在 Grace Hopper 系统上,我们建议您使用至少为系统中 GPU 内存总大小的四分之一到一半的交换文件。

Libvirt 网络#

  • 对于裸机部署,如果安装了 libvirt,libvirt 会添加 iptables 规则,以允许进出连接到 INPUT、FORWARD、OUTPUT 和 POSTROUTING 链中 virbr0 设备的访客的流量。如果不需要虚拟化,删除这些规则可以提高网络性能。

  • 对于不需要 libvirt 的裸机环境,禁用 libvirt 服务并删除 libvirt 安装的 iptables 规则可以提高网络性能。

要删除 libvirt 规则,请停止 libvirtd 服务或手动删除网络规则。

警告

仅在裸机环境中禁用 libvirt 服务或删除 iptables 规则。这些步骤将破坏现有的 libvirt 部署。

  • 停止 libvirtd 服务

    如果没有虚拟机并且不需要虚拟化,请禁用 libvirtd.service 并重新启动以清除规则并删除 virbr0 接口。

    sudo systemctl stop libvirtd
    sudo systemctl disable libvirtd
    sudo reboot now
    
  • 仅删除网络规则

    删除这些规则的另一种方法是运行以下命令以停用 libvirt 网络。此操作将删除 virbr0 网桥,终止 dnsmasq 进程,并删除 iptables 规则。

    停用名为 default 的 libvirt 网络

    virsh net-destroy default
    

    防止网络在启动时自动启动

    virsh net-autostart --network default --disable
    

    要还原更改,请重新激活默认的 libvirt 网络

    virsh net-start default*
    

注意

如果需要 libvirt,请避免 NAT,并考虑对虚拟机使用 NIC 直通或 SR-IOV 以获得最佳性能。使用 libvirt 进行性能优化不在本指南的范围之内。