摘要
早期我们的CPU是对称多处理器,之所以叫对称是因为他们能够对等的去访问整个内存空间,CPU访问内存是通过内存访问控制芯片(内存控制器)进行,CPU是通过内存控制器对内存进行读写操作
我们计算机有五个大计算部件,但是这个五个大部件在服务器上运行的时候像CPU很可能不止一颗了,多个CPU之间或者多核CPU之间是如何互联的?每个CPU都是通过一个socket接到主板上的,每个CPU很可能内部有多个核心,因此而言每个CPU每个核心甚至是每个超线程对应的核心他们都会被识别成一个逻辑cpu,核心可能是物理的,cpu可能也是物理的,但是核心上可能支持超线程功能,所以一个物理CPU可能表现为多个逻辑CPU。多颗CPU彼此之间是如何进行通信的?我们是如何进行做队列访问的?早起所谓的SMP(Symmetric Multi-Processor,对称多处理结构,之所以被称为对称处理器是因为他们能够对等的访问整个内存空间),实际上CPU访问内存时是通过内存控制器的芯片进行的。CPU和内存连接是通过多根总线来完成的,通过内存控制器向内存发起寻址定址之后,内存控制权在内部的某些虚拟电路将内存指定地址内的位置跟CPU建立关联关系从而实现接通电路,接通电路后就是有电压的为1,没电压的为0这样的标识,从而完成数据传输。所哟通过内存控制器,谁请到内存控制器谁就使用对应的内存,大家知道我们CPU本来就比内存快,而内存又只有一段,如果内存控制器也只有一段,4颗CPU同时访问内存将会导致系统效率很低
于是就出现了NUMA(Non-Uniform Memory Access,非一致性内存访问),每一个socket上插入的物理CPU都有一段自己使用的内存(也就是我们所说的本地节点),而非本地节点都称之为远程节点,而离自己进的节点称之为邻居节点,简单来讲就是每段内存都有内存控制器,每一个CPU在使用数据时尽可能的向本地内存控制器发送请求,而且这些内存控制器在本地完成数据存储,如果本地内存没有数据,这时候CPU就会向本地内存控制器发出信号让其去他内存控制器上查询数据,在其他内存控制器查询到数据后再返回给本地内存控制器,然后本地内存控制器再给CPU,所以这种情况下性能是有很大的下降的。
因此在NUMA体系结构中为了保证一个进程尽可能的在CPU上运行时保证其数据的存储和指令的存储都在本地节点进行,那么我们是不是应该将进程绑定在CPU上是不是?哪怕只有一颗CPU,我们也应该将进程绑定在CPU上,哪怕不是多对称服务器也是这个道理。这又是为什么呢?仅仅一颗CPU但是其内部是不是还是有很多核心的呢?这些核心彼此间使用内存数据很可能也是一段内存空间,如果是多核心CPU我们是否应该强制绑定呢?做了强制绑定我们至少避免了上下文切换带来的系统开销。如果只有一颗CPU也只有一个核心那倒无所谓了。
假如说,我们在一个多核心CPU服务器运行两个Nginx进程上下文切换,于是我们隔离了两个核心的cpu,不让其他进程使用(此隔离操作是在系统启动时进行的,系统启动时像内核传递参数(方法isoicpus=0,1 指定 0 1两个核心)指定后,系统启动时不会调用任何进程到这两个cpu核心上。),但是这不意味着CPU不处理中断,所以某些IO硬件设备在其中断注册时仍然会被分配到被隔离的两个CPU上处理,也就意味这这两个进程仍然会被打断,为了避免这种情况我们可以将某些IO中断从这两个cpu上隔离,不让这两个CPU处理中断,这样才会叫专用CPU,有时候我们需要去调整 把某个中断请求的向量绑定在某个CPU上,我们可以通过查看所有的中断请求分配情况是否和我们的CPU隔离政策是否有相违背的地方,如果有,我们需要挪出去,这些动作就是我们所谓的CPU、中断、进程调优。