什么是NUMA,我们为什么要了解NUMA

news2024/11/27 7:28:32

在IA多核平台上进行开发时,我们经常会提到NUMA这个词 ,那么NUMA到底指的是什么?我们怎么可以感受到它的存在?以及NUMA的存在对于我们编程会有什么影响?今天我们一起来看一下。

1、NUMA的由来

NUMA(Non-Uniform Memory Access),即非一致性内存访问,是一种关于多个CPU如何访问内存的架构模型,早期,在计算机系统中,CPU是这样访问内存的:

图片

在这种架构中,所有的CPU都是通过一条总线来访问内存,我们把这种架构叫做SMP架构(Symmetric Multi-Processor),也就是对称多处理器结构。可以看出来,SMP架构有下面4个特点:

  • CPU和CPU以及CPU和内存都是通过一条总线连接起来

  • CPU都是平等的,没有主从关系

  • 所有的硬件资源都是共享的,即每个CPU都能访问到任何内存、外设等

  • 内存是统一结构和统一寻址的(UMA, Uniform Memory Architecture)

SMP架构在CPU核不多的情况下,问题不明显,有实验证明,SMP服务器CPU利用率最好的情况是2至4个CPU:

图片

但是随着CPU多核技术的发展,一颗物理CPU中集成了越来越多的core,导致SMP架构的性能瓶颈越来越明显,因为所有的处理器都通过一条总线连接起来,因此随着处理器的增加,系统总线成为了系统瓶颈,另外,处理器和内存之间的通信延迟也较大。

为了解决SMP架构下不断增多的CPU Core导致的性能问题,NUMA架构应运而生,NUMA调整了CPU和内存的布局和访问关系,具体示意如下图:

图片

在NUMA架构中,将CPU划分到多个NUMA Node中,每个Node有自己独立的内存空间和PCIE总线系统。各个CPU间通过QPI总线进行互通。

CPU访问不同类型节点内存的速度是不相同的,访问本地节点的速度最快,访问远端节点的速度最慢,即访问速度与节点的距离有关,距离越远访,问速度越慢,所以叫做非一致性内存访问,这个访问内存的距离我们称作Node Distance。

虽然NUMA很好的解决了SMP架构下CPU大量扩展带来的性能问题,但是其自身也存在着不足,当Node节点本地内存不足时,需要跨节点访问内存,节点间的访问速度慢,从而也会带来性能的下降。所以我们在编写应用程序时,要充分利用NUMA系统的这个特点,尽量的减少不同CPU模块之间的交互,避免远程访问资源,如果应用程序能有方法固定在一个CPU模块里,那么应用的性能将会有很大的提升。

2、NUMA架构下的CPU和内存分布

在Linux系统上,可以查看到NUMA架构下CPU和内存的分布情况,不过在这之前,我们先得理清几个概念:

  • Socket:表示一颗物理 CPU 的封装(物理 CPU 插槽),简称插槽。为了避免将逻辑处理器和物理处理器混淆,Intel 将物理处理器称为插槽,Socket表示可以看得到的真实的CPU核 。

  • Core:物理 CPU 封装内的独立的一组程序执行的硬件单元,比如寄存器,计算单元等,Core表示的是在同一个物理核内逻辑层面的核。同一个物理CPU的多个Core,有自己独立的L1和L2 Cache,共享L3 Cache。

  • Thread:使用超线程技术虚拟出来的逻辑 Core,需要 CPU 支持。为了便于区分,逻辑 Core 一般被写作 Processor。在具有 Intel 超线程技术的处理器上,每个内核可以具有两个逻辑处理器,这两个逻辑处理器共享大多数内核资源(如内存缓存和功能单元)。此类逻辑处理器通常称为 Thread 。超线程可以在一个逻辑核等待指令执行的间隔(等待从cache或内存中获取下一条指令),把时间片分配到另一个逻辑核。高速在这两个逻辑核之间切换,让应用程序感知不到这个间隔,误认为自己是独占了一个核。对于每个逻辑线程,拥有完整独立的寄存器集合和本地中断逻辑,共享执行单元和一二三级Cache,超线程技术可以带来20%~30%的性能提升。

  • Node:即NUMA Node,包含有若干个 CPU Core 的组。

Socket、Core和Threads之间的关系示意如下:

图片

在Linux系统中,可以用lscpu查看NUMA和CPU的对应关系:

图片

从上图可以看到,这台服务器有两个NUMA node,有两个Socket,每个Socket也就是一个物理CPU,有4个逻辑Core,每个逻辑Core有两个线程(服务器开启了超线程),所以总共的CPU个数(以超线程计数)为:2*4*2 = 16个。

使用numactl -H命令可以看到NUMA下的内存分布:

图片

所以这台服务器上CPU和内存在NUMA下的分布如下:

图片

NUMA架构下的CPU,先从逻辑Core开始编号,如果开启了超线程,就从Core总数的后面继续编号,例如上图中从cpu8开始之后的都是开启超线程之后的CPU线程。

另外,在实际编程中,我们还可以通过numastat命令查看NUMA系统下内存的访问命中率:

图片

  • numa_hit:成功分配给此节点的页面数量。

  • numa_miss:由于预期节点上的内存较低,在此节点上分配的页面数量。每个 numa_miss 事件在另一个节点上都有对应的 numa_foreign 事件。

  • numa_foreign:最初用于分配给另一节点的页面数量。每个 numa_foreign 事件在另一节点上都有对应的 numa_miss 事件。

  • interleave_hit:成功分配给此节点的交集策略页面数量。

  • local_node:此节点上的进程在这个节点上成功分配的页面数量。

  • other_node:通过另一节点上的进程在这个节点上分配的页面数量。

如果miss值和foreign值越高,就要考虑线程绑定以及内存分配使用的问题。

需要注意的是,NUMA Node和socket并不一定是一对一的关系,在AMD的CPU中,可能更多见于NUMA Node比socket个数多(一般AMD的CPU的NUMA可以在BIOS中进行配置),而Intel的CPU中,NUMA Node可能比socket的个数还少。

例如在下面这台服务器上,使用的是AMD的EPYC 7001,NUMA有8个,但是Socket只有两个:

图片

3、NUMA架构下的编程

NUMA架构显著的特点就是CPU访问本地内存快,访问远程内存慢。所以我们在NUMA架构下编写程序,要扬长避短,多核多线程编程中,我们要尽可能的利用CPU Core的亲和性,将线程绑定到对应的CPU上,并且该线程从该CPU对应的本地内存上去申请内存,这样才能最大限度发挥NUMA架构的优势,达到比较好的处理性能。

简单来说,就是本地的处理器、本地的内存来处理本地的设备上产生的数据。如果有一个PCI设备(比如网卡)在Node0上,就用Node0上的核来处理该设备,处理该设备用到的数据结构和数据缓冲区都从Node0上分配。

在DPDK中,有一个rte_socket_id()函数,可以获取当前线程所在的NUMA Node,在使用DPDK提供申请内存的接口中,一般都需要传入参数NUMA id,也是基于提高NUMA架构下的报文转发性能考虑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/764343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL(十):MySQL语法-进阶

MySQL语法-进阶 数据类型Text 类型Number 类型Date 类型 ASALTER TABLEconcat、group_concatSQL注入阻止SQL注入方案一方案二方案三 HAVING 子句临时表正则表达式获取服务器元数据事务导出数据导出数据导出表作为原始数导出SQL格式的数据 导入数据解决无法导入问题使用 LOAD DA…

kali linux 安装python 3xx 以及多版本切换的方式

简介 在渗透测试的时候,我们通常会用到不同的工具,这些工具可能对python的版本要求不一样,这个时候我们可能就需要在kali上面安装不同版本的python,以及灵活的切换python的版本。 下载python3并安装 以python38来举例&#xff…

Visual Studio 中的新特性:可视化宏扩展

今天,我们很高兴地宣布在 Visual Studio 17.7 预览版中推出可视化宏扩展功能。这个新功能通过可视化的方式对宏代码进行逐步扩展。 若要开始使用此功能,请确保你的 Visual Studio 版本更新到最新版本的 Visual Studio 预览版。 下面,我们来看…

图解Vit 3:Vision Transformer——ViT模型全流程拆解

文章目录 Layer NormalizationClassification TokenPosition embeedding 先把上一篇中的遗留问题解释清楚:上图中,代码中的all_head_dim就是有多少head。把他们拼接起来。 Encoder在Multi-Head Self-Attention之后,维度一直是BND,…

python flask 通过页面输入python代码,执行结果返回页面

1,不太好用 项目结构 app.py from flask import Flask, render_template, request import io import sysapp Flask(__name__)app.route(/) def index():return render_template(index.html)app.route(/execute, methods[POST]) def execute():code request.form[…

B071-项目实战-用户模块--手机注册 管理员登录

目录 完成注册功能后端开发完成UserControllerUserServiceImplLogininfoMapper 前端页面完成绑定数据绑定事件准备登录页 管理员登录1需求分析登录设计页面设计表设计流程设计所需技术 员工新增级联操作登录信息EmployeeServiceImplShopServiceImpl 管理员登录2前端页面后端接口…

Learning to cartoonize using white-box cartoon representations

论文笔记--漫画生成--White-box Cartoon Representations - 知乎论文 Learning to Cartoonize Using White-box Cartoon Representations 源码https://github.com/SystemErrorWang/White-box-Cartoonization效果算法概述这篇论文是将图像风格转成漫画风格,作者认为可…

MySQL索引index

目录 1.索引的概念 2.索引的优缺点 3.索引的数据结构 4.索引结构 1.二叉树: ​编辑2.红黑树: 3.BTree(B-Tree): ​编辑4.传统BTree: ​编辑5.MySQL中的BTree: ​编辑6.Hash&#xf…

浅谈电子设备之电磁屏蔽箱设计要点

屏蔽箱又称隔离箱、屏蔽盒和电磁屏蔽箱,可以对传导和辐射进行处理,为无线通讯产品生产制造提供高效的隔离测试环境,测试内容包含耦合测试、RF功能测试、电磁干扰测试和电磁兼容性测试。屏蔽箱多采用铝合金材料设计,屏蔽材料阻隔能…

C语言模拟实现字符串处理函数

需要多一点点勇气,来面对变差的自己 大家好,我是纪宁。 这篇文章为大家带来的是5大字符串处理函数的模拟实现。 文章目录 1.strlen函数的模拟实现 2.strcpy函数的模拟实现 3.strcmp函数的模拟实现 4.strcat函数的模拟实现 5.strstr函数的模拟实现…

相机标定-基础(一)

1. 何为相机标定? 当相机拍摄照片时,我们看到的图像通常与我们实际看到的不完全相同。这是由相机镜头引起的,而且发生的频率比我们想象的要高。 这种图像的改变就是我们所说的畸变。一般来说,畸变是指直线在图像中出现弯曲或弯曲。 这种畸变我们可以通过相机标定来进行解…

反常积分题目

目录 题目1: 题目2: 题目3:​ 题目4: 题目5: 题目6: 题目7: 我们首先引入反常积分的定义: CSDNhttps://mp.csdn.net/mp_blog/creation/editor/131676865 题目1: 题目2…

STM32 ws2812b多屏驱动程序

文章目录 前言一、ws2812b的数据传输以及屏幕的组合二、代码ws2812screen.c文件ws2812screen.h文件主函数 前言 在上篇文章中使用了stm32的dmatim的方式点亮了ws2812b的灯 但是我的需求不仅仅是点亮他,我需要他像屏幕一样显示某一些东西,ws2812显示有一…

深入学习 Redis - 全局命令、过期策略如何实现、高效定时器原理

目录 Redis 全局命令 get 和 set keys keys 使用注意事项 exists exists 使用注意事项 del del 使用注意事项 expire 【面试经典】redis 中 key 的过期策略是怎么实现的? 定时器实现原理(非 Redis 实现,拓展) 1.基于 …

21 - 队列 - 循环队列——队列的顺序表示和实现

前面我们学习数组队列,链式队列,我们今天来学习循环队列。 队列的定义 队列(Queue)也是一种线性表, 但是它仅能在一端进行插入,而另一端进行删除的操作 ,插入的一端称为 队尾rear,删除的一端称为 队头front 。 向一个栈插入新元素又称作进队或入队, 从一个栈删除元素…

从实体按键看 Android 车载的自定义事件机制

在汽车数字化、智能化变革的进程中,越来越多的车机设计或部分、或全部地舍弃了实体按键,进而把车主操作的入口转移到了车机 UI 以及语音助手。 但统一、高效的零层级 UI 颇为困难,语音的准确率、覆盖率亦不够完善,那么在当下的阶段…

【数据结构】文件的归并排序

目录 1、归并排序引申出的问题 2、磁盘与文件的关系---包含与被包含的关系 3、思路: 4、代码实现 1、归并排序引申出的问题 归并排序是最常用的外排序的方法(但归并排序既可进行内部排序也可进行外部排序),外排序就是在磁盘中…

LLaMA(Open and Efficient Foundation Language Models )论文解读(二)

此篇博客主题:LLAMA模型数据、训练时长、功耗及碳排放量 LLaMA: Open and Efficient Foundation Language Models paper https://arxiv.org/pdf/2302.13971v1.pdf 1 训练样本 Overall, our entire training dataset contains roughly 1.4T tokens after tokenization. For mo…

2023年Q2京东厨卫大电市场分析报告(京东运营数据分析)

随着新产品推广和消费需求升级,今年Q2,京东厨卫大电市场的销售额突破百亿,从同环比来看均呈增长趋势。百亿市场中,油烟机、电热水器、燃气热水器这三大品类占据较大份额,这一期,我们重点来看一下京东厨卫大…

怎么用Postman脚本中发送请求

Postman的Collection(集合)/Folder(集合的子文件夹)/Request(请求)都有Pre-request script和Tests两个脚本区域, 分别可以在发送请求前和请求后使用脚本(基于Javascript实现各种操作) 在遇到有依赖的接口时,比如需要登录或者需要从前一个接口的结果中获取参数时,我们往往需要在…