BCLinux 6 性能调优手册


  • BCLinux Developers

    BCLinux 6 性能调优手册


    1 CPU

    1.1 CPU 拓扑

    1.1.1 使用 taskset 设置 CPU 亲和性

    taskset 搜索并设定运行进程的 CPU 亲和性(根据进程 ID)。它还可用于启动给定 CPU 亲和性的进程,这样就可将指定的进程与指定的 CPU 或者一组 CPU 绑定。但 taskset 不保证本地内存分配。如果您需要本地内存分配的额外性能利益,我们建议您使用 numactl,而不是 taskset。

    CPU 亲和性使用位掩码表示。最低位对应第一个逻辑 CPU,且最高位对应最后一个逻辑 CPU。这些掩码通常是十六进制,因此 0x00000001 代表处理器 0,0x00000003 代表处理器 3 和 1。
    要设定运行进程的 CPU 亲和性,请执行以下命令,使用处理器或者您要绑定到的处理器掩码替换 mask,使用您要更改亲和性的进程的进程 ID 替换 pid。

    # taskset -p mask pid  
    

    要启动给定亲和性的进程,请运行以下命令,使用处理器或者您要绑定的处理器的掩码替换mask,使用程序、选项以及您要运行的程序参数替换 program。

    # taskset mask -- program  
    

    除了将处理器指定为位码,您还可以使用 -c 选项提供逗号分开的独立处理器,或者一组处理器列表,类似如下:

    # taskset -c 0,5,7-9 -- myprogram   
    

    1.1.2 使用 numactl 控制 NUMA 策略

    numactl 使用指定的调度或者内存放置策略运行进程。所选策略是为那个进程及其所有子进程设定。numactl 还可以为共享内存片段或者文件设定永久策略,并设定 CPU 亲和性和进程的内存亲和性。它使用 /sys 文件系统设置系统拓扑。

    /sys 文件系统包含有关 CPU、内存和外设是如何通过 NUMA 互联连接的。特别是/sys/devices/system/cpu 目录中包含有关系统的 CPU 是如何互相连接的信息。/sys/devices/system/node 目录包含有关系统中 NUMA 节点以及那些节点间相对距离的信息。

    在 NUMA 系统中,处理器和内存条之间的距离越大,处理器访问那个内存条的速度就越慢。应将对性能敏感的程序配置为可以从最接近的内存条分配内存。

    还应将对性能敏感的程序配置为在一组核上执行,特别是在多线程程序的情况下。因为一级缓存一般都很小,如果在一个核中执行多个线程,每个线程有可能清除之前线程访问的缓冲的数据。当操作系统尝试在这些线程间执行多任务,且线程总是清除其他的缓存的数据时,则大部分的执行时间将用于缓存线替换。这个问题也称缓存贬值。因此建议您将多线程的程序绑定到节点而不是单一核,因为这样可以让线程在多个层级(第一、第二和最后一级缓存)共享缓存线,并尽量减小缓存填充操作的需要。但如果所有线程都访问同一缓存的数据,则将程序绑定到单一核可能获得高性能。

    numactl 可让您将程序绑定到特定核或者 NUMA 节点,同时在与那个程序关联的核或者一组核上分配内存。numactl 提供的一些有用选项有:

    --show  
    	显示当前进程的 NUMA 策略设置。这个参数不需要进一步的参数,且可按以下方式使用:numactl --show。  
    
    --hardware  
    	显示系统中可用节点清单。  
    
    --membind  
    	只从指定节点分配内存。当使用这个参数时,如果这些节点中的内存不足则分配会失败。这个参数的用法为 numactl --membind=nodes program,其中 nodes 是您要从中分配内存的节点列表,program 是要从那个节点分配内存的程序。节点号可以采用用逗号分开的列表、范围或者两者的结合方式提供。有关详情请参考 numactl man page: man numactl
    
    --cpunodebind  
    	只执行属于指定节点的 CPU 中的命令(及其子进程)。这个参数的用法为 numactl--cpunodebind=nodes program,其中 nodes 是指定程序(program)要绑定的 CPU 所属节点列表。节点号可以采用用逗号分开的列表、范围或者两者的结合方式提供。有关详情请参考 numactl man page: man numactl  
    
    --physcpubind  
    	只执行指定 CPU 中的命令(及其子进程)。这个参数的用法为 numactl --physcpubind=cpu program,其中 cpu 是用逗号分开的物理 CPU 号列表,这些数据在 /proc/cpuinfo 的processor 字段中显示,program 是应只在哪些 CPU 中执行的程序。还要将 CPU 指定为与当前cpuset 关联。详情请参考 numactl man page:man numactl。  
    
    --localalloc  
    	指定永远要在当前节点中分配的内存。 
    
    --preferred  
    	在可能的情况下分配到指定节点中的内存。如果内存无法分配到指定的节点,则返回其他节点。这个选项只能有一个节点号,例如:numactl --preferred=node。    
    

    1.1.3 NUMA 亲和性管理守护进程(numad)

    numad 是一个自动NUMA亲和性管理守护进程,它监控系统中的NUMA拓扑以及资源使用以便动态提高NUMA资源分配和管理(以及系统性能)。

    根据系统负载,numad 可对基准性能有 50% 的提高。要达到此性能优势,numad 会周期性访问 /proc文件系统中的信息以便监控每个节点中的可用系统资源。该守护进程然后会尝试在有足够内存和 CPU 资源的 NUMA 节点中放置大量进程以优化 NUMA 性能。目前进程管理阈值为至少是一个 CPU 的 50%,且至少有300 MB 内存。numad 会尝试维护资源使用水平,并在需要时通过在 NUMA 节点间移动进程平衡分配。

    numad 还提供放置前建议服务,您可以通过各种任务管理系统进行查询以便提供CPU初始绑定以及进程内存资源的支持。这个放置前建议服务无论系统中是否运行numad都可以使用。

    numad 有两种使用方法:
    * 作为服务使用
    * 作为可执行文件使用

    将 numad 作为服务使用
    在 numad 服务运行时,它将会尝试根据其负载动态调节系统。要启动该服务,请运行:

    # service numad start
    

    要让该服务在重启后仍保留,请运行:

    # chkconfig numad on
    

    将 numad 作为可执行文件使用

    要将 numad 作为可执行文件使用,请运行:

    # numad
    

    numad 将运行直到将其停止。在它运行时,其活动将被记录到 /var/log/numad.log 文件中。