[转帖]Intel关NUMA的内存编址

intel,numa,内存,编址 · 浏览次数 : 0

小编点评

**内存分配** * Intel 的NUMA实现后,应用向OS申请内存的最小单元是4KB的page。 * 应用向OS申请内存的最小单元可以分布到多个socket上。 * 一般情况下应用访存会相对均匀地分布在不同socket上。 **NUMA的实现** * NUMA的实现往往差别很大。 * 这以后再说。 **应用性能** * Intel 的NUMA实现后,应用向OS申请内存的最小单元可以分布到多个socket上。 * 应用向OS申请内存的最小单元可以相对均匀地分布在不同socket上。 * 应用程序向OS申请内存的最小单元可以相对均匀地分布到多个socket上。 * 上面的测试用例是有意为之, 访存在socket间并不均匀。 **结论** * Intel 的NUMA实现后,应用向OS申请内存的最小单元可以分布到多个socket上。 * 应用向OS申请内存的最小单元可以相对均匀地分布在不同socket上。 * 应用程序向OS申请内存的最小单元可以相对均匀地分布到多个socket上。 * 上面的测试用例是有意为之, 访存在socket间并不均匀。

正文

https://zhuanlan.zhihu.com/p/454928730

 

最近在做某国产化平台相关的适配, 不管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. ​

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

这样我们知道当前配置使用地址位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的实现往往差别很大, 这个以后再说.

引用

与[转帖]Intel关NUMA的内存编址相似的内容:

[转帖]Intel关NUMA的内存编址

https://zhuanlan.zhihu.com/p/454928730 最近在做某国产化平台相关的适配, 不管NUMA的性能和实现方式都和Intel有较大不同, 作为比较对象, 理解Intel的NUMA实现是很有必要的. 虽然从软件角度, 打开NUMA会带来额外的复杂度, 但是从硬件角度, 关

[转帖]超线程 Smt 究竟可以快多少?

https://www.51cto.com/article/686171.html 刚才我们关闭SMT是把CPU10-CPU19全关了,只留下每对里面的1个CPU,也就是留下了CPU0-CPU9。 默认情况下是Intel I9,10核,每个核2个threads,共20个CPUs: 下面编译内核: 需

[转帖]Intel至强可扩展处理器 Skylake-SP(Purley 最新一代至强)购买指南

前言 Intel Purley平台,Skylake-SP,至强可扩展处理器(铂金、黄金、白银、青铜)发售了,共58颗处理器。 这些处理器里哪些值得购买?哪些是骗小白的?它们各自的定位如何?本文将帮助你解决问题。 本文将会按照使用场景将这58颗处理器分类,并通过不同处理器在各自应用场景的性价比剔除一些

[转帖]Intel/英特尔、Mellanox/迈络斯 infiniband交换机型号对比及参数描述

Intel/英特尔、Mellanox/迈络斯 infiniband交换机型号对比及参数描述http://qlogic.blog.bokee.net/bloggermodule/blog_viewblog.do?id=17662812 字体大小:大 | 中 | 小2014-05-09 12:14 阅读

[转帖]Intel正式发布第三代至强可扩展处理器,单芯最多可达40核

https://baijiahao.baidu.com/s?id=1673640229820868010&wfr=spider&for=pc 今天晚上Intel正式发布了第三代至强可扩展处理器,也就是说了很久的Ice Lake-SP,这是他们首款10nm工艺的数据中心处理器,现在个处理器最多拥有40

[转帖]Intel寄存器的艺术

https://www.oschina.net/translate/the-art-of-picking-intel-registers?print 我为一本名为Scene Zine的在线杂志写了这篇文章。 Scene Zine 致力于 Demo Scene,它是一个数字艺术社区,致力于通过音乐,艺

[转帖]Intel VROC: 高性能的NVMe SSD软RAID功能

https://www.modb.pro/db/586867 在前面的文章 LSI/Broadcom的Tri-Mode 里介绍过Broadcom新推出的Tri-Mode芯片已经可以支持NVMe SSD了,SAS3500 ROC(RAID On Chip)芯片还支持多块NVMe SSD的硬RAID功能

[转帖]Intel PAUSE指令变化如何影响MySQL的性能

https://zhuanlan.zhihu.com/p/581200704 导读 x86、arm指令都很多,无论是应用程序员还是数据库内核研发大多时候都不需要对这些指令深入理解,但是 Pause 指令和数据库操作太紧密了,本文通过一次非常有趣的性能优化来引入对 Pause 指令的理解,期望可以事半

[转帖]Intel、海光、鲲鹏920、飞腾2500 CPU性能对比

https://plantegg.github.io/2021/06/18/%E5%87%A0%E6%AC%BECPU%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94/ Intel 海光 鲲鹏920 飞腾2500 CPU性能对比 为了让程序能快点,特意了解了CPU的各种原理,

[转帖]Intel甘拜下风,挤牙膏比不过兆芯CPU

https://baijiahao.baidu.com/s?id=1735997557665412214 本文比较长,有万字左右,因此在前面先把小标题集中亮个相。 即使大家一晃而过,我也要让精心拟定的各个小标题有个露脸机会。 兆芯承运应时生,抢得先机石成金, 架海擎天担重任,同德一心报国恩。 多核增