SMP

在计算机早期,大部分计算机在主板上装备了一块芯片,叫做微处理器或单核CPU。这些处理器与主板上其它元件的通信通过一个连接器或Socket来完成。处理器之间通过系统总线进行通信是非常低效的,经常发生的性能瓶颈,无法最大化利用CPU的计算能力。

为了改善这个处境,诞生了多核技术。多核是复制一些CPU单元到同一块处理器上,比如寄存器或者一级缓存,两个执行线程可共享数据。这种方式加速多个被处理的进程,比传统的单个核心(未开启多核)提供更高的整体性能。

SMP(Symmetric Multi-Processing)技术,即对称多处理器结构。每个处理器的地位都是平等的,对内存的使用权限也相同。任何一个程序或进程、线程都可以分配到任何一个处理器上运行,在操作系统的支持下,可以达到非常好的负载均衡,让整个系统的性能、吞吐量有较大提升。但是,由于多个核使用相同的总线访问内存,随着核数的增长,内存访问冲突将迅速增加,总线将成为瓶颈,制约系统的扩展性和性能。

image

NUMA

由于SMP集中式共享存储器的设计限制了处理器访问存储器的频次,导致处理器可能会经常处于对数据访问的饥饿状态。为了更好解决问题,NUMA架构诞生了。

NUMA架构将多个核组成一个节点(Node),每一个节点相当于是一个对称多处理机(SMP),一块CPU的节点之间通过On-chip Network通讯,不同的CPU之间采用Hydra Interface实现高带宽低时延的片间通讯。在NUMA架构下,整个内存空间在物理上是分布式的,所有内存的集合就是整个系统的全局内存。每个核访问内存的时间取决于内存相对于处理器的位置,访问本地内存(本节点内)会更快一些。Linux内核从2.5版本开始支持NUMA架构,现在的操作系统也提供了丰富的工具和接口,帮助我们完成就近访问内存的优化和配置。

image

亲和性与绑核

亲和性(Affinity)是进程要在某个给定的CPU上尽量长时间地运行而不被迁移到其他处理器的倾向性。在多核运行的机器上,每个CPU本身自己会有缓存,缓存着进程使用的信息,而进程可能会被OS 调度到其他CPU上,CPU Cache命中率就低了,当绑定CPU后,程序就会一直在指定的CPU跑,不会由操作系统调度到其他CPU上。这样能够大大提高CPU Cache的命中率,提高性能。

使用shell命令,把进程运行的任务绑定在NUMA和CPU上。

numactl是Linux提供了一个手工调优的命令,可以指定进程在某个NUMA node上运行或者特定的CPU核心上运行。

可先在Linux系统中先查询NUMA节点信息以及拓扑结构numactl -H

  1. 绑NUMA:numactl —cpubind=0 —membind=0
  2. 绑CPU核心:numactl -C 0-19 —membind=0
  3. 验证绑核是否成功:top命令也可以显示CPU被分配给哪个进程。
在程序代码中通过系统API调用指定。

利用glibc库中的sched_getaffinity接口,我们获取应用程序当前的cpu亲和性,而通过sched_setaffinity接口则可以把应用程序绑定到固定的某个或某几个cpu上运行。

接口定义如下:

#include <sched.h>
int sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);
int sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);
void CPU_CLR(int cpu, cpu_set_t *set);
int CPU_ISSET(int cpu, cpu_set_t *set);
void CPU_SET(int cpu, cpu_set_t *set);
void CPU_ZERO(cpu_set_t *set);

示例:

#include <sched.h>
#include <stdio.h>
// 绑定当前进程到CPU0
cpu_set_t cpu_mask;
CPU_ZERO(&cpu_mask);    // 清空集合,确保所有位为0
CPU_SET(0, &cpu_mask); // 将CPU0设置为可调度
if (sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask) == -1) {
    perror("sched_setaffinity failed");
} else {
    // 绑定成功
}

NUMA-aware && L3 Cache

鲲鹏编程与调优指南 多核与NUMA NUMA非统一内存访问结构

CacheLine

MariaDB性能调优案例

鲲鹏性能优化十板斧