关闭CPU超线程以提升集群性能

E-HPC集群的每个计算节点都是一台ECS实例,默认情况下,ECS实例均已开启CPU超线程。在部分HPC场景下,需要关闭CPU超线程以获得更好的性能表现。本文介绍如何关闭计算节点的CPU超线程。

背景信息

CPU是中央处理器,一个CPU可以包含若干个物理核,通过超线程HT(Hyper-Threading)技术可以将一个物理核变成两个逻辑处理核。ECS的超线程基于HT技术,允许在一个物理核上并发地运行两个线程(Thread),一个线程可以视为一个vCPU,vCPU是ECS实例的虚拟处理核。在部分HPC场景下,需要关闭计算节点的CPU超线程,使得计算节点获得更好的性能表现。

注意事项

各类型实例规格是否支持关闭超线程如下:

  • 仅部分企业级x86计算规格的ECS实例支持关闭超线程,具体请参见规格限制

  • 弹性裸金属服务器不支持直接关闭超线程,但可以从软件层面关闭超线程。

  • 超级计算集群SCC默认已关闭超线程。

企业级x86计算规格实例关闭超线程

创建集群后,如果需要扩容计算节点,可以配置扩容的计算节点是否开启超线程。

重要

对于企业级x86计算规格的ECS实例,创建后不支持关闭超线程。

手动扩容

手动扩容时,在新建节点页签下,可以配置实例是否开启HT。具体操作,请参见手动扩容集群

手动扩容关闭HT-..png

自动伸缩

配置自动伸缩时,在全局配置区域,可以配置实例是否开启HT。具体操作,请参见配置自动伸缩

自动伸缩配置HT..png

弹性裸金属服务器关闭超线程

弹性裸金属服务器可以在实例创建后在软件层面(GuestOS内部)关闭超线程,包括设置nr_cpus和改变vCPU状态两种方式。GuestOS内部要关闭HT,实际上是要模拟一个物理核上对应一个逻辑核,所以将每个物理核上的对应一个逻辑核关闭,保留一个物理核对应一个逻辑核就能达到关闭超线程的效果,可以理解为offline一半的vCPU,且这些vCPU均一一分布在对应的物理核上。

说明

对于裸金属服务器,实际需要在主板BIOS上关闭超线程,这涉及到硬件重启,链路较长且相对较慢,无法保证SLA。因此提供设置两种软件层面的方式,可以实现类似关闭超线程的效果。

方式

优点

缺点

设置nr_cpu

lscpucpuid等命令返回看到的内部实际使用CPU数就是物理CPU数,不会看到offline的vCPU,基本达到关闭超线程的效果和CPU核数显示。

  • 一旦设置了nr_cpus=实例规格vCPU/2,offline的一半vCPU在实例运行的情况下无法再使用,必须要删除nr_cpus参数,然后重启实例才能恢复所有vCPU。

  • 如果设置了nr_cpus=实例规格vCPU/2,建议您在创建自定义镜像前删除该参数,否则如果使用自定义镜像创建不同规格的实例,会碰到只能识别部分物理核的情况,此时必须要重新设置nr_cpus。

改变vCPU状态

通过命令改变vCPU状态时无需重启实例。配置后可以使用echo 1 > /sys/devices/system/cpu/cpu$cpunum/online恢复offline的vCPU且无需重启实例。

  • lscpucpuid等命令返回的信息中可以看到对应offline的vCPU。

  • 有些License检测到的还是全量CPU。

  • 实例重启后,需要重新设置一次。

重要

由于实际生产业务多样,阿里云无法真实模拟上述两种方式是否会对业务产生影响。在实际生产环境中使用两种软件层面的方式关闭超线程时,请您务必做好测试,确认是否对您的业务有所影响。

设置nr_cpus

nr_cpus是一个内核参数,作用是限定内核最大支持的CPU数量,取值范围为2~255。如果要实现关闭超线程的效果,可以设置nr_cpus=实例规格vCPU/2,这样内核支持的最大CPU数量就只有实际规格的一半,实际只使用一半的vCPU,达到offline一半vCPU的要求,并且nr_cpus offline的一半vCPU均是lscpu命令可以看到的后一半vCPU,实际对应offline的就是每个物理核上的一个逻辑核。

以ecs.ebmc6me.16xlarge规格为例,该规格有64个vCPU,操作系统是CentOS 7,设置nr_cpus的操作步骤如下:

  1. 远程连接弹性裸金属服务器。具体操作,请参见通过密码或密钥认证登录Linux实例

  2. 执行lscpu命令查看vCPU情况,确认实例是否已开启超线程。

    预期返回如下,如果CPU(s)的值和实例规格的vCPU数一致,且Thread(s) per core为2,则表明该实例开启了超线程。

    裸金属CPU..png

  3. 修改grub文件。

    vim /boot/grub2/grub.cfg

    i进入编辑模式,添加nr_cpus=实例规格vCPU/2,此处示例为nr_cpus=32。然后按Esc键退出编辑模式,输入:wq保存配置。

    裸金属CPU111..png

  4. 重启ECS实例。

  5. 查看效果。

    1. 执行lscpu命令查看vCPU情况。

      预期返回如下,可以看到CPU(s)为32,且Thread(s) per core为1,表明实例已关闭超线程。

      裸金属CPU1..png

    2. 执行lscpu --extend命令,确认vCPU分布情况。

      预期返回如下,可以看到32个vCPU分布在32个物理核上,实现了关闭超线程的效果。

      裸金属CPU11..png

改变vCPU状态

您可以通过命令改变vCPU的状态,实现offline一半vCPU,即offline每个物理核的一个逻辑核。

以ecs.ebmc6me.16xlarge规格为例,该规格有64个vCPU,操作系统是CentOS 7,改变vCPU状态的操作步骤如下:

  1. 远程连接弹性裸金属服务器。具体操作,请参见通过密码或密钥认证登录Linux实例

  2. 执行lscpu命令查看vCPU情况,确认实例是否已开启超线程。

    预期返回如下,如果CPU(s)的值和实例规格的vCPU数一致,且Thread(s) per core为2,则表明该实例开启了超线程。

    裸金属CPU..png

  3. 创建并执行脚本,改变vCPU状态。

    1. 创建脚本。

      vim test.sh

      脚本内容如下:

      #!/bin/bash
      for cpunum in $(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | cut -s -d, -f2- | tr ',' '\n' | sort -un)
      do
          echo 0 > /sys/devices/system/cpu/cpu$cpunum/online
      done
    2. 执行脚本。

      sh test.sh
  4. 查看效果。

    1. 执行lscpu命令查看vCPU情况。

      预期返回如下,可以看到后32个vCPU已经offline,且Thread(s) per core为1,表明实例已关闭超线程。

      裸金属CPU22..png

    2. 执行lscpu --extend命令,确认vCPU分布情况。

      预期返回如下,可以看到后32个vCPU已经offline,且均为每个物理核上的一个逻辑核。

      裸金属CPU2..png