Intel关NUMA的内存编址

news2025/7/16 15:19:24

最近在做某国产化平台相关的适配, 不管NUMA的性能和实现方式都和Intel有较大不同, 作为比较对象, 理解Intel的NUMA实现是很有必要的. 虽然从软件角度, 打开NUMA会带来额外的复杂度, 但是从硬件角度, 关闭NUMA其实更复杂, 本文尝试分析关闭NUMA时Intel平台的内存编址.

Memory Interleaving

Interleaving是一种基本的编址方式, 可以将连续的物理内存地址映射到不同的内存模块, 比如[0, 256)映射到模块0, [256, 512)映射到模块1, 物理内存分配一般以4KB或者更大粒度的页为分配单位, 这样即使是单线程的程序也能充分发挥底层内存模块的并发性. Interleaving按照内存的层次一般分为Socket, Channel和Rank等, DIY过电脑的同学可能还记得双通道, 也就是Channel Interleaving, 本文主要关心Socket Interleaving, 也就是关闭NUMA时的内存编址. Interleaving的基本思想见下图:

Intel Socket Interleaving

这里以Intel(R) Xeon(R) CPU E5-2682 v4为例, 基于Broadwell EP架构, 其他Intel的CPU应该大致相同. 测试机器插了2个CPU, 内存Interleaving的信息可以从对应的PCI配置空间拿到, 具体到Broadwell EP, 其PCI设备地址是固定的.

#xxd /sys/bus/pci/devices/0000:ff:0f.4/config
0000000: 8680 fc6f 0000 0000 0100 8008 0000 8000  ...o............
0000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000020: 0000 0000 0000 0000 0000 0000 8680 e06f  ...............o
0000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000040: 1111 1111 1111 1100 0000 0000 0000 0000  ................
0000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000060: c107 0804 0044 1155 c007 0804 0000 0000  .....D.U........
0000070: c007 0804 0000 0000 c007 0804 0000 0000  ................
0000080: c007 0804 0000 0000 c007 0804 0000 0000  ................
0000090: c007 0804 0000 0000 c007 0804 0000 0000  ................
00000a0: c007 0804 0000 0000 c007 0804 0000 0000  ................
00000b0: c007 0804 0000 0000 c007 0804 0000 0000  ................
00000c0: c007 0804 0000 0000 c007 0804 0000 0000  ................
00000d0: c007 0804 0000 0000 c007 0804 0000 0000  ................
00000e0: c007 0804 0000 0000 c007 0804 0000 0000  ................
00000f0: c007 0804 0000 0000 c007 0804 0000 0000  ................

Interleaving的信息从地址0x60开始, 具体格式如下, 因为当前机器内存插法是balanced, 只有一个有效region.

继续看其中SAD region的编码:

这里只有一个有效SAD Region, 它的值为c107 0804, 我们来计算一下上面的这些值:

  • limit. ((0x040807c1L >> 6) & 0xfffff) << 26 = 551836188672L. 该机器上有512GB内存, 被这一个region完全覆盖
  • flip96 = 1
  • disableXOR = 0

再来看一下target list的编码, target list用于找到内存地址对应的numa node.

这样我们知道0044 1155对应到的8个target分别是{0, 0, 0, 0, 1, 1, 1, 1}. 从这个角度看, 这款CPU至多能支持到8个NUMA node. ​

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! !   

最后看下该机器使用哪些地址位来决定:

这样我们知道当前配置使用地址位a18, a17, a16以及a8, a7, a9来决定物理地址到NUMA node的映射关系.

测试

为了验证上面的理论, 我们设计一个测试程序:

  • 通过Intel提供的pcm-memory.x来观察每个socket的访存带宽, 从而反映出访问了哪个socket上的内存
  • 使用相对较大的一片内存, 这样可以避免cache带来的影响
  • 8个target分别是{0, 0, 0, 0, 1, 1, 1, 1}, 所以可以知道i2决定了映射到哪个socket, 只要固定a18, 那么就是a8决定了映射到哪个socket
  • 因为决定映射关系的最高位是a18, 使用hugepage (2MB)来简化逻辑
int main()
{
  const size_t sz = 4ULL * 1024 * 1024 * 1024;
  void *buf = mmap(NULL, sz, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
  size_t i = 0, j = 0;
  size_t setsz = 1<<8;  // a8 decides socket index

  while (1) {
    for (i = 0; i < sz; i += 1<<19) {
      for (j = 0; j < 1<<16; j += 1<<9) {
        memset(buf + i + j, 0, setsz);
      }
    }
  }

  munmap(buf, sz);
  return 0;
}

上面程序执行时, 用pcm-memory.x观察可以验证上面的分析

  • 除了少许背景流量, 所有的内存写操作都发生在socket 0上
  • 减小setsz, 比如128, 可以预期所有内存写操作依然发生在socket 0上
  • 加大setsz, 比如512, 可以预期2个socket上都有写流量

另外也可以看到, 即使在socket 1上没有写流量, 还是有和socket 0上接近的读流量, 而且这些读流量是该测试引起的, 也就是发生了预读, 只不过这些预读都是无效的.

|---------------------------------------||---------------------------------------|
|--             Socket  0             --||--             Socket  1             --|
|---------------------------------------||---------------------------------------|
|--     Memory Channel Monitoring     --||--     Memory Channel Monitoring     --|
|---------------------------------------||---------------------------------------|
|-- Mem Ch  0: Reads (MB/s):   652.12 --||-- Mem Ch  0: Reads (MB/s):   642.34 --|
|--            Writes(MB/s):   629.02 --||--            Writes(MB/s):    68.15 --|
|-- Mem Ch  1: Reads (MB/s):   636.40 --||-- Mem Ch  1: Reads (MB/s):   628.23 --|
|--            Writes(MB/s):   613.17 --||--            Writes(MB/s):    54.10 --|
|-- Mem Ch  2: Reads (MB/s):   651.87 --||-- Mem Ch  2: Reads (MB/s):   644.78 --|
|--            Writes(MB/s):   628.28 --||--            Writes(MB/s):    67.77 --|
|-- Mem Ch  3: Reads (MB/s):   638.41 --||-- Mem Ch  3: Reads (MB/s):   628.78 --|
|--            Writes(MB/s):   615.29 --||--            Writes(MB/s):    51.96 --|
|-- NODE 0 Mem Read (MB/s) :  2578.80 --||-- NODE 1 Mem Read (MB/s) :  2544.13 --|
|-- NODE 0 Mem Write(MB/s) :  2485.77 --||-- NODE 1 Mem Write(MB/s) :   241.98 --|
|-- NODE 0 P. Write (T/s):     502663 --||-- NODE 1 P. Write (T/s):     532451 --|
|-- NODE 0 Memory (MB/s):     5064.57 --||-- NODE 1 Memory (MB/s):     2786.11 --|
|---------------------------------------||---------------------------------------|
|---------------------------------------||---------------------------------------|
|--                 System Read Throughput(MB/s):       5122.93                --|
|--                System Write Throughput(MB/s):       2727.74                --|
|--               System Memory Throughput(MB/s):       7850.68                --|
|---------------------------------------||---------------------------------------|

总结

综上我们验证了在Intel的机器上, 连续的物理地址以较小粒度分布在不同的socket上, 测试机上是256B, 最小可以配置到64B的粒度. 应用程序向OS申请内存的最小单元是4KB的page, 该page必然会分布到多个socket上, 一般情况下应用访存会相对均匀地分布在不同socket, 反应到应用的性能上就显得比开NUMA更加稳定, 上面的测试用例是有意为之, 访存在socket间并不均匀. ​

当我们知道Intel的关NUMA实现后, 很容易有先入为主的想法, 以为其他平台也是类似实现, 但是因为各种原因, NUMA的实现往往差别很大, 这个以后再说.

引用

  • https://os.itec.kit.edu/downloads/publ_2017_hillenbrand_xeon_decoding.pdf
  • https://www.geeksforgeeks.org/types-of-memory-interleaving/

原文链接:https://zhuanlan.zhihu.com/p/454928730

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

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

相关文章

java+springboot基于性别网上学习特征问卷调查及可视化系统

基于JSP技术、SSM框架、B/S机构、Mysql数据库设计并实现了性别网上学习特征及可视化。系统主要包括个人中心、用户管理、调查问卷管理、用户答卷管理、专家建议管理、学习攻略管理、我的收藏管理、爬虫管理、系统管理等功能模块。 (1)绪论 网站的开发背景&#xff0c;意义和系…

栈和队列(带图,有手就废)

文章目录1.栈1.1栈的概念与结构1.2栈的声明1.3动态栈的实现1.3.1初始化栈1.3.2入栈1.3.3出栈1.3.4获取栈顶元素1.3.5获取栈中元素个数1.3.6判断栈是否为空1.3.7销毁栈1.4栈的总结2.队列2.1队列的概念与结构2.2队列的声明2.3队列的实现2.3.1初始化队列2.3.2入队2.3.3出队2.3.4获…

BUUCTF web之WarmUp 源代码详解

目录 前言 PHP代码分析 关于../ 前言 访问除了一张滑稽图&#xff0c;就没其他的了 查看源码&#xff0c;有一个注释了的 source.php&#xff0c;可以尝试直接访问一下。同时进行目录扫描 访问source.php&#xff0c;里面包含php代码&#xff0c;题目说了是php代码审计&…

知识经验分享——YOLOv5-6.0训练出错及解决方法(RuntimeError)

>>>深度学习Tricks&#xff0c;第一时间送达<<< 目录 一、问题bug 二、解决方法 步骤1&#xff1a;打开utils/loss.py文件 步骤2&#xff1a;找到 for i in range(self.nl) 函数&#xff08;CtrlF&#xff09;&#xff0c;作以下替换&#xff1a; 步骤3…

VMware创建Win10操作系统虚拟机

VMware创建Win10操作系统虚拟机1. 安装VMware162. 下载Win10镜像3. 创建虚拟机4. 安装Win105. 安装VMware Tools工具1. 安装VMware16 迅雷云链接&#xff1a;https://pan.xunlei.com/s/VNH9mkbxLqnyB_F_g0h73C_TA1?pwdsdi4# 2. 下载Win10镜像 百度云链接&#xff1a;https:…

优雅的实现符合开闭原则的流水日志抽取demo

如何做出一个标准化记录流水日志(Demo) 昨天晚上 在b站刷到了 极海Channel 海哥的视频 也想去跟着实现一个,作为学习的demo,主要学习思路 可能存在的问题: 可能每一个需要收集的类里取参数的字段可能是不一样的如何去处理如何可以让他更好的作用于新的业务代码上 项目代码日志…

c++STL库

什么是STLSTL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。STL的版本原始版本Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本&#xff0c…

阿里首次公开企业级 SpringBoot 实战进阶笔记

Spring Boot 的重要性不需要我多说了吧&#xff0c;Java程序员们应该都懂&#xff0c;不仅面试会被提问&#xff0c;工作中也非常需要spring boot 不知道大家是如何学习Spring Boot的&#xff0c;据我所知&#xff0c;很多开发者会试着在网上找一些开源项目&#xff0c;通过阅…

马上2023了,云原生架构还不懂?阿里云原生架构笔记带你完全拿下

前言 软件架构发展至今&#xff0c;经历了从单体架构、垂直架构、SOA 架构到现在的以微服务、服务网格等云原生技术为主的演变过程&#xff0c;云原生技术发展势不可挡&#xff0c;老生常谈的“云原生”将依然会是未来的热门话题。而且随着数字化转型加速&#xff0c;企业对于…

Spring Data JPA之自动创建数据库表

Spring Data JPA之自动创建数据库表前言Spring Data JPA demo实现步骤导入依赖创建实体类编辑application.yml文件配置数据库连接和jpa配置运行测试总结如果博主的文章对您有所帮助&#xff0c;可以评论、点赞、收藏&#xff0c;支持一下博主!!!前言 由于在项目中使用到了Spri…

C++11中篇

文章目录1. 右值引用和移动语义1.1 左值引用和右值引用1.2 左值引用与右值引用比较1.3 右值引用使用场景和意义1.5 完美转发2. default 和delete1. 右值引用和移动语义 1.1 左值引用和右值引用 传统的C语法中就有引用的语法&#xff0c;而C11中新增了的右值引用语法特性&#…

Java_抽象类

目录 1.抽象类语法 2.抽象类特性 3.抽象类的作用 抽象类概念&#xff1a;在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是反过来&#xff0c;并不是所有的类都是用来描绘对象的&#xff0c;如果 一个类中没有包含足够的信息来描绘一个具体的对…

RabbitMQ远程访问

文章目录1. 创建用户2. 关闭防火墙开启端口3. 测试远程访问参考链接背景问题 guest这个用户只能使用localhost登录&#xff0c;而不能使用IP地址登录&#xff1a; amqp://guest:guest127.0.0.1:5672/rabbitVHost 远程无法连接amqp://guest:guest10.10.10.128:5672/rabbitVHost …

Elasticsearch simple(2)ElasticSearch windows本地环境搭建(V8.5.1)

切记安装Kibana的版本要和所安装的elasticsearch版本号完全一致。 这里&#xff1a; elasticsearch-8.5.1 kibana-8.5.1 elasticsearch默认端口为9200&#xff1b; Kibana默认端口为5601。 1 elasticsearch的下载和安装 下载官网&#xff1a;https://www.elastic.co/cn/down…

ArcGIS影像TIF拼接

ArcGIS影像TIF拼接 我们要使用的工具是Mosaic To New Raster 这个工具通过下面的路径找到&#xff1a; &#xff08;我用的是ArcGIS 10.8&#xff09; 输入影像 在这里输入多张待拼接的TIF 输出文件和路径 Output Loacation是输出文件的路径&#xff0c;可以是文件夹名称或…

MATLAB | MATLAB海洋、气象数据colormap配色补充包(NCL color tables)

众所周知&#xff0c;海洋、气象、水文等一系列学科绘制图像时&#xff0c;因很多时候涉及要将陆地海洋分开或者应对一些非常特殊的情况&#xff0c;因此有很多非常特别的colormap&#xff0c;我之前虽然做过一些常用colormap的补充包但是依旧是无法完全应对各种特殊的colormap…

C语言-基础

C-基础参考变量/常量左值/右值&#xff1f;&#xff1f;&#xff1f;字面量/常量变量作用域全局变量与局部变量作用域扩展 python数据与地址存储类autoregisterstaticextern数据类型基本类型整数类型进制数原码/补码/反码int 与 char数值溢出浮点类型字符型字符与整数字符与进制…

Selenium隐藏浏览器和元素截屏实践

文章目录隐藏浏览器介绍示例代码浏览器截图介绍示例代码对整个浏览器页面进行截屏指定特定HTML元素进行截屏隐藏浏览器 介绍 在使用Selenium采集网页数据时&#xff0c;需要不断地调用浏览器。实际上&#xff0c;通过对Selenium的设置&#xff0c;可以达到隐藏浏览器的效果。…

堆 (带图详解)

文章目录1.堆的基本概念1. 概念2.性质1.必须为完全二叉树2.满足大堆/小堆成立的条件3.存储方式1.逻辑结构2.物理结构4. 孩子与父亲之间下标的关系2.堆的基本实现1.push——插入1.代码2. 情况分析情况1情况23. 向上调整算法1.过程分析2. 临界条件的判断2. pop—— 删除1.代码2. …

[附源码]计算机毕业设计JAVA火车票订票管理系统

[附源码]计算机毕业设计JAVA火车票订票管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM myba…