问题标签 [numa]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
187 浏览

multiprocessing - x86_64 机器上的 NUMA 模拟

我想知道是否有一种方法可以通过某种模拟工具在 x86_64 机器上执行特定于 NUMA 架构的实验。

我发现了一些关于创建假 NUMA 节点的资源,但不知道如何准确地使用它们。如果有办法,虚拟机也可以。

谢谢,

0 投票
2 回答
822 浏览

c++ - 使用 numa_alloc_onnode() 分配小块是否有限制?

我正在一台有 4 个 Operton 6272 处理器、运行 centOS 的机器上试验 NUMA。有 8 个 NUMA 节点,每个节点有 16GB 内存。

这是我正在运行的一个小型测试程序。

所以基本上一个在核心 #0 上运行的线程在 NUMA 节点 5 上分配 131K 100 字节缓冲区,用垃圾初始化它们并泄漏它们。每 10 次迭代,我们打印出有关每个 NUMA 节点上可用内存量的信息。

在输出的开头,我得到:

最后我得到:

我不清楚的事情:

1)为什么会有那些“mbind:无法分配内存”消息?事实上,如果我将缓冲区大小更改为 1000,我远未用完所有内存,并且行为不会改变,这让我认为我用完了某种内核资源句柄.

2) 即使我要求在节点 5 上分配内存,实际分配似乎已经在节点 0 和 5 之间分配。

任何人都可以就为什么会发生这种情况提供任何见解吗?

更新

想就第(2)点提供更多细节。一些内存未在节点 5 上分配的事实似乎与我们正在初始化核心 #0(属于 NUMA 节点 0)上的缓冲区这一事实有关。如果我更改pin_to_core(0)为,pin_to_core(8)则分配的内存将在节点 1 和 5 之间拆分。如果是,pin_to_core(40)则所有内存都分配在节点 5 上。

更新2

我查看了 libnuma 的源代码,并尝试将调用替换为numa_alloc_onnode()来自那里的更多低级调用:mmap()mbind(). 我现在还在检查内存驻留在哪个 NUMA 节点上——我为此使用了move_pages()调用。结果如下。在初始化(循环j)之前,页面没有映射到任何节点(我得到 ENOENT 错误代码),并且在初始化之后,页面被分配给节点 0 或节点 5。模式是常规的:5,0,5,0 ,... 和以前一样,当我们接近第 131000 次迭代时,调用mbind()开始返回错误代码,发生这种情况时,页面总是分配给节点 0。 mbind 返回的错误代码是 ENOMEM,文档说这意味着“内核内存”用完。我不知道它是什么,但它不可能是“物理”内存,因为我每个节点有 16GB。

所以到目前为止,这是我的结论:

  1. 当另一个 NUMA 节点的核心首先接触内存时,由 NUMA施加的内存映射限制mbind()仅保持 50%。我希望这被记录在某个地方,因为悄悄地违背承诺并不好......

  2. 调用次数有限制mbind。所以应该尽可能mbind()大的内存块。

我要尝试的方法是:在固定到特定 NUMA ndo 内核的线程上执行内存分配任务。为了让您更加安心,我将尝试调用 mlock(因为这里描述的问题)。

0 投票
0 回答
328 浏览

multithreading - Intel/AMD OpenCL CPU 运行时不支持 CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN

条件:

我安装了 AMD OpenCL 版本AMD-APP-SDK-v2.8-lnx64和 Intel OpenCL 版本 *intel_sdk_for_ocl_applications_xe_2013_r2_sdk_3.1.1.11385_x64*(版本识别不能更复杂)根据具有双插槽Xeon的 HPC 服务器上的描述E5-2650、Xeon Phi 协处理器、64GB 主机内存和 Red Hat Enterprise Server 6.4。

问题描述:

我想用OpenCL做设备裂变来解决NUMA问题。不幸的是,设备(英特尔 CPU)或者 Linux 内核似乎不支持CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN。我尝试了 Intel OpenCL 和 AMD OpenCL。尽管 AMD OpenCL 设备查询说它支持关联域选项,但实际上并不支持:当我尝试使用 CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN 运行代码时,clCreateSubDevices() 函数返回 -30 错误代码。根据论坛帖子,我猜这是当前英特尔 OpenCL 驱动程序中的一个错误。

潜在的解决方案:

我认为如果我可以选择前 16 个并行计算核心(8 个核心 + 8 个超线程)(在总共 32 个并行计算核心中),它们将映射到第一个套接字。不幸的是,英特尔 OpenCL 将 16 个并行计算内核随机分布在 32 个内核中。另一方面,AMD OpenCL 选择了前 16 个并行计算内核,但 OpenCL 编译器在我正在运行的内核上表现不佳。所以没有免费的午餐定理也适用于此。

问题:

  1. 有什么方法可以指定 OpenCL 应该使用哪些并行计算核心进行计算?
  2. 有什么办法可以用 OpenCL 克服这个 NUMA 问题?

欢迎对 NUMA 亲和力的体验发表任何评论。

谢谢!


更新

部分解决方法,仅适用于单插槽测试:

(在 Linux 中)禁用一个 NUMA 节点的所有内核,因此 OpenCL ICD 只能从另一个 NUMA 节点的硬件线程中进行选择。例如。在 2 插座 32 HTT 系统上:

我不确定这种黑客攻击是否没有副作用,但到目前为止它似乎有效(至少用于测试)。

0 投票
2 回答
2502 浏览

c++ - NUMA:如何检查 C++ 数组分配在 RAM 的哪个部分?

我有一个有 2 个 CPU 和 64GB 内存的服务器,每个 CPU 32GB。

我知道每个 CPU 都有自己的 RAM 部分,我们称它们为 RAM1 和 RAM2。我想让我的程序知道它在哪个 RAM(RAM1 或 RAM2)上分配它的数据。

我试图检查指针值:

但输出看起来是随机的。我想那是因为地址是虚拟的。虚拟内存地址和部分RAM之间是否有对应关系?

如何检查我的数组“a”分配在哪个 RAM 中?

0 投票
2 回答
437 浏览

c++ - 多线程:为什么两个程序比一个程序好?

很快关于我的问题:

我有一台带有 2 个 AMD Opteron 6272 插槽和 64GB RAM 的计算机。

我在所有 32 个内核上运行一个多线程程序,与我在一个 16 核插槽上运行 2 个程序的情况相比,速度降低了 15%。

如何制作一个程序版本和两个程序一样快?


更多细节:

我有大量任务,想要完全加载系统的所有 32 个内核。所以我将任务按 1000 个分组打包。这样一个组需要大约 120Mb 的输入数据,在一个内核上完成大约需要 10 秒。为了使测试更理想,我将这些组复制了 32 次,并使用 ITBB 的parallel_for循环在 32 个内核之间分配任务。

pthread_setaffinity_np用来确保系统不会让我的线程在内核之间跳转。并确保所有核心都被依次使用。

mlockall(MCL_FUTURE)用来确保系统不会让我的内存在套接字之间跳转。

所以代码看起来像这样:

只有计算时间对我来说很重要,因此我在单独的parallel_for循环中准备输入数据。并且不包括时间测量中的准备时间。

现在我在 32 个内核上运行所有这些,看到每秒约 1600 个任务的速度。

然后我创建了两个版本的程序,tasksetpthread确保首先在第一个套接字的 16 个内核上运行,第二个在第二个套接字上运行。&我在 shell 中使用简单的命令将它们一个一个地运行:

这些程序中的每一个都达到了约 900 个任务/秒的速度。总计 >1800 个任务/秒,比单程序版本多 15%。

我想念什么?

我认为问题可能出在库中,我仅将其加载到集合线程的内存中。这会是个问题吗?我可以复制库数据以便在两个套接字上独立使用吗?

0 投票
1 回答
935 浏览

mongodb - MongoDB、NUMA 硬件、页面错误但有足够的 RAM 用于工作集、触摸命令或 vmtouch/dd 未加载到内存中

MongoDB 2.46 和 2.4.8

用例:

  1. 在具有 2 个索引的集合上加载 100.000 个文档。常驻内存增加(mongostat),并且不会发生页面错误。
  2. 重启 mongod。常驻内存低(这是预期的)
  3. 尝试使用触摸命令 db.runCommand({ touch: collection, data: true, index: true })或其他方式“预热”mongo(在操作系统上,vmtouch / dd上)
    a)在这一步,在我的开发机器上( MacOS),我在 mongostat 中看到很多页面错误试图加热它(预期的)并且驻留内存被提升。从那时起,任何更新都不会引发页面错误
    b)在 numa 服务器(256 GB RAM)上,即使我使用本指南启动 mongo:http: //docs.mongodb.org/manual/administration/production-笔记/#mongodb-on-numa-hardware(注意:我没有超级用户访问权限。但是,第二步,在 /proc/sys/vm/zone_reclaim_mode 中回显 0,已经是 0,所以我就这样离开了),我似乎无法预热使用“触摸”命令记忆。没有任何反应,即使它成功返回。在 mongostat 中,只有 'mapped' 和 'vsize' 越来越高,并且驻留内存相同 (35m)。我什至尝试使用 vmtouch 和 dd 命令加载操作系统内存中的数据文件。仅重新索引集合会更改常驻内存。

在我开始将数据加载到服务器后一段时间,问题就开始了。我做了很多 upserts,一开始的性能很棒(3000 - 4000 upserts/sec)。这是意料之中的,因为工作集将能够放入内存中。在 30.000.000 个文档之后,该过程似乎产生了很多页面错误,我不知道为什么。数据文件约为。33GB,性能约为 500 upserts/sec,有很多页面错误。这应该意味着工作集不在内存中。但是,256GB RAM 应该绰绰有余. 我尝试了 'touch' 命令,但常驻内存很低(我什至重新启动了 mongod 进程,运行了 touch 命令,即使 'mapped' 和 'vsize' 飙升到很多 GB,常驻内存仍然很低,35m) . 我试图重新索引集合,瞧,常驻内存从 35m -> 20GB。但是,我再次看到页面错误。然后我尝试 vmtouch 数据文件(或使用 dd)。同样,很多页面错误。

问题是我不能'只有' 500 upserts/sec。我应该改变我的应用程序逻辑吗?我认为使用 256GB 内存,我的“活动”工作集(预计为 60GB)应该适合内存。我在中间(30GB),似乎我无法解决这个问题。是numa硬件吗?我应该进行任何其他更改吗?

提前致谢

0 投票
2 回答
1916 浏览

cpu - 哪种架构可以调用非统一内存访问 (NUMA)?

根据wiki:非统一内存访问(NUMA)是一种用于多处理的计算机内存设计,其中内存访问时间取决于相对于处理器的内存位置。

但尚不清楚它是关于包括缓存在内的任何内存还是仅与主内存有关。

例如 Xeon Phi 处理器有下一个架构:在此处输入图像描述

所有内核对主内存 (GDDR) 的内存访问都是相同的。同时,不同的内核对二级缓存的内存访问是不同的,因为首先检查本机二级缓存,然后通过环检查其他内核的二级缓存。是 NUMA 还是 UMA 架构?

0 投票
2 回答
240 浏览

linux-kernel - 在 NUMA 中,每个 CPU 是否也有类似于本地 RAM 的本地 I/O 控制器?

在非统一内存访问中,每个 CPU 是否都有自己的 I/O 控制器?我知道在 NUMA 中,每个 CPU 都有自己的本地 RAM。就像每个处理器都在运行一个单独的进程。他们可以使用 IPC 机制(如 Socket 等)相互交谈。我只是想知道就像每个本地 RAM 一样,他们也有本地 I/O 控制器吗?

0 投票
2 回答
1871 浏览

linux - 如何解释 numademo 输出

numademo 实用程序(是 numactl 包的一部分)随许多流行的 linux 发行版(RHEL、SLES、...)一起提供。我试图找出与此工具相关的任何文档,但找不到任何有用的信息。要么没有人使用它,要么每个使用它的人都知道它。

这是一个示例输出

2个节点可用

我需要知道这些测试是如何进行的?

如何解释这些结果?

例如:什么会导致以下数字出现巨大差异。

谢谢,哈莎娜

0 投票
1 回答
472 浏览

multithreading - NUMA 系统、虚拟页面和虚假共享

据我了解,对于 NUMA 系统的性能,有两种情况需要避免:

  1. 同一套接字中的线程写入同一高速缓存行(通常为 64 字节)
  2. 来自不同套接字的线程写入同一虚拟页面(通常为 4096 字节)

一个简单的例子会有所帮助。假设我有一个双插槽系统,每个插槽都有一个带有两个物理内核的 CPU(和两个逻辑内核,即每个模块没有 Intel 超线程或 AMD 两个内核)。让我借用OpenMP 上的图表:for schedule

因此,基于案例 1,最好避免线程 0 和线程 1 写入相同的缓存行,基于案例 2,最好避免线程 0 写入与线程 2 相同的虚拟页面。

但是,我被告知,在现代处理器上,第二种情况不再是问题。套接字之间的线程可以有效地写入相同的虚拟页面(只要它们不写入相同的缓存行)。

案例二不再是问题了吗?如果它仍然是一个问题,那么正确的术语是什么?将这两种情况称为一种虚假分享是否正确?