问题标签 [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 投票
2 回答
12753 浏览

java - NUMA 架构如何影响 ActivePivot 的性能?

我们正在将 ActivePivot 应用程序迁移到新服务器(4 插槽 Intel Xeon,512GB 内存)。部署后,我们启动了我们的应用程序基准测试(这是大型 OLAP 查询与实时事务并发的混合)。测得的性能几乎比我们以前的服务器慢两倍,以前的服务器具有相似的处理器,但内核数量减少了两倍,内存减少了两倍。

我们调查了两台服务器之间的差异,看起来大的一台具有NUMA 架构(非统一内存访问)。每个 CPU 插槽在物理上接近内存的 1/4,但距离其余部分更远……运行我们的应用程序的 JVM 分配了一个大的全局堆,每个 NUMA 节点上都有该堆的随机部分。我们的分析是内存访问模式非常随机,CPU 内核经常浪费时间访问远程内存。

我们正在寻找有关在 NUMA 服务器上利用 ActivePivot 的更多反馈。我们可以配置 ActivePivot 多维数据集或线程池、更改查询、配置操作系统吗?

0 投票
5 回答
1045 浏览

parallel-processing - 多核 CPU:避免令人失望的可扩展性的编程技术

我们刚刚购买了一台 32 核 Opteron 机器,我们得到的加速有点令人失望:超过 24 个线程,我们根本看不到加速(实际上总体上变慢了),大约 6 个线程后,它变得明显亚线性。

我们的应用程序对线程非常友好:我们的工作分解为大约 170,000 个小任务,每个小任务都可以单独执行,每个任务需要 5-10 秒。它们都从同一个大小约为 4Gb 的内存映射文件中读取。他们偶尔会对其进行写入,但每次写入可能需要 10,000 次读取 - 我们只是在 170,000 个任务的每一个结束时写入一点数据。写入受锁定保护。分析表明锁不是问题。线程在非共享对象中使用大量 JVM 内存,它们对共享 JVM 对象的访问很少,其中只有一小部分访问涉及写入。

我们在启用了 NUMA 的 Linux 上使用 Java 进行编程。我们有 128Gb 内存。我们有 2 个 Opteron CPU(型号 6274),每个 CPU 有 16 个内核。每个 CPU 有 2 个 NUMA 节点。在英特尔四核(即 8 核)上运行的相同作业几乎可以线性扩展到 8 个线程。

我们尝试将只读数据复制到每个线程一个,希望大多数查找可以在 NUMA 节点本地进行,但我们观察到这并没有加速。

对于 32 个线程,“top”显示 CPU 的 74%“us”(用户)和大约 23%“id”(空闲)。但是没有睡眠,几乎没有磁盘 i/o。使用 24 个线程,我们得到 83% 的 CPU 使用率。我不确定如何解释“空闲”状态 - 这是否意味着“等待内存控制器”?

我们尝试打开和关闭 NUMA(我指的是需要重新启动的 Linux 级别设置)并且没有发现任何区别。启用 NUMA 时,“numastat”仅显示大约 5% 的“分配和访问未命中”(95% 的缓存未命中发生在 NUMA 节点本地)。[编辑:] 但是添加“-XX:+useNUMA”作为 java 命令行标志给了我们 10% 的提升。

我们的一个理论是我们正在最大化内存控制器,因为我们的应用程序使用了大量的 RAM,并且我们认为有很多缓存未命中。

我们可以做些什么来(a)加速我们的程序以接近线性可伸缩性,或者(b)诊断正在发生的事情?

另外:(c)我如何解释“顶部”结果-“空闲”是否意味着“在内存控制器上被阻塞”?(d) Opteron 与 Xeon 的特性有什么不同吗?

0 投票
0 回答
715 浏览

cpu - 解释不同 NUMA 节点上的 perf 工具结果

我想使用 perf 工具解释我的程序的一个有趣行为。

一些背景资料

我的机器有 4 个 NUMA 节点,我的主要应用程序正在机器上运行。使用 cpusets 我对机器进行分区,为应用程序提供 3 个节点,为系统提供 1 个节点。在同一台机器上运行单元测试(用于记录改进)时,我得到了我正在尝试使用 perf 工具进行调查的意外行为。

出乎意料的行为是,在应用程序正在运行的 NUMA 节点上(比如说 node2),我在 unittest 上获得了更好的时间,大约是 unittest 在具有系统的 NUMA 节点上运行时的两倍(比如说节点 3)。看起来像在 node2 的 CPU 上运行(一个不做自旋锁的 cpu)我得到比在另一个 numa 上运行更好的结果。

我正在尝试改进我的日志记录系统,因此测试正在进行的工作也由应用程序完成,将一些日志消息写入队列以便稍后转储到磁盘(不同的线程)。对队列的争用由自旋锁 (CAS) 控制。unitest 是一个具有 2 个循环的写入器线程:100 次,将 1000 条日志写入队列,RDTSC(我的选择)用于测量每个内部循环,然后打印统计信息。队列足够大,我得到一个标准偏差,内存操作减少到最低限度(没有 memcpy)。阅读器正在转储到另一个线程上的磁盘。

我尝试停止我的应用程序并再次运行测试。在这种情况下,我看到无论选择哪个 NUMA 节点来运行我的测试,我都会得到与在 node3 上运行类似的结果(慢),这意味着如果我在同一个 numa 上运行我的测试,正在运行的应用程序正在加速我的测试应用程序运行的节点。对我来说非常不直观。

使用以下 perf 工具命令获取一些数据

并使用命令进行分析

我提取了我看到的包含一些差异的内容。 不确定我是否应该怀疑 sched-、LLC-、branch-、TLB,因为我不知道相对差异是否解释了我看到的行为。

有什么更好的调查方法的建议吗?

0 投票
0 回答
1314 浏览

c - NUMA系统中使用mbind移动页面

我正在尝试了解numa(3)Linux 上的库。

我分配了一个大数组(许多 GB 的内存)。在随机 NUMA 节点上运行的线程写入它,因为这样的页面在随机 NUMA 内存节点上出现故障(默认 NUMA 策略)。

在线程计算结束时,我有一个单线程作业来总结结果。为此,我首先压缩数组,删除大量元素,然后将剩余部分移动到主线程的 NUMA 节点。

系统move_pages调用不适合这项工作,因为它需要每个页面的数组条目 - 开销太大。

文档不清楚是否可以强制numa_tonode_memory移动故障内存。

所以我看到的唯一方法是使用mbindwith MPOL_MF_MOVE,但我无法理解创建一个正确的nodemask参数(或者其他东西失败了)。据我所知,这是:

来自/usr/include/numa.h

有时我得到mbind: Bad address,有时调用成功,但随后的内存访问给出了SIGSEGV.

addr始终是由返回的有效指针

并且len是页面对齐的。

我怎样才能用尽可能少的系统调用来完成这项工作,并且没有随之而来的大量开销move_pages

建立nodemask论点的正确方法是mbind什么?

0 投票
2 回答
1982 浏览

c++ - NUMA 架构上大 (8MB) 内存区域的可扩展分配

我们目前正在使用 TBB 流程图,其中 a) 并行过滤器处理数组(与偏移量并行)并将处理后的结果放入中间向量(在堆上分配;大多数向量将增长到 8MB)。然后将这些向量传递给节点,然后节点根据它们的特征对这些结果进行后处理(在 a) 中确定)。由于资源同步,每个特征只能有一个这样的节点。我们编写的原型在 UMA 架构上运行良好(在单个 CPU Ivy Bridge 和 Sandy Bridge 架构上进行了测试)。但是,该应用程序无法在我们的 NUMA 架构(4 CPU Nehalem-EX)上扩展。我们将问题归结为内存分配并创建了一个最小示例,其中我们有一个并行管道,它只从堆中分配内存(通过 8MB 块的 malloc,然后 memset 8MB 区域;类似于最初的原型会做的)直到一定的内存量。我们的发现是:

  • 在 UMA 架构上,应用程序随着管道使用的线程数线性扩展(通过 task_scheduler_init 设置)

  • 在 NUMA 架构上,当我们将应用程序固定到一个套接字(使用 numactl)时,我们会看到相同的线性放大

  • 在 NUMA 架构上,当我们使用多个套接字时,我们的应用程序运行时间会随着套接字数量的增加而增加(负线性比例-“向上”)

对我们来说,这听起来像是堆争用。到目前为止,我们尝试的是用 Intel 的 TBB 可扩展分配器代替 glibc 分配器。但是,在单个套接字上的初始性能比使用 glibc 更差,在多个套接字上的性能没有变差,但也没有变得更好。我们使用 tcmalloc、hoard 分配器和 TBB 的缓存对齐分配器获得了相同的效果。

问题是是否有人遇到过类似的问题。堆栈分配对我们来说不是一个选项,因为我们希望即使在管道运行之后也保留堆分配的向量。一个堆如何在 NUMA 架构上从多个线程有效地分配 MB 大小的内存区域?我们真的很想保持动态分配方法,而不是预先分配内存并在应用程序中管理它。

我使用 numactl 附加了各种执行的性能统计信息。Interleaving/localalloc 没有任何效果(QPI 总线不是瓶颈;我们验证了使用 PCM,QPI 链路负载为 1%)。我还添加了一个图表,描述了 glibc、tbbmalloc 和 tcmalloc 的结果。

perf stat bin/原型 598.867

'bin/prototype' 的性能计数器统计信息:

perf stat numactl --cpunodebind=0 bin/prototype 272.614

'numactl --cpunodebind=0 bin/prototype' 的性能计数器统计信息:

perf stat numactl --cpunodebind=0-1 bin/prototype 356.726

'numactl --cpunodebind=0-1 bin/prototype' 的性能计数器统计信息:

perf stat numactl --cpunodebind=0-2 bin/protoype 472.794

'numactl --cpunodebind=0-2 bin/prototype' 的性能计数器统计信息:

最小示例:使用 g++-4.7 std=c++11 -O3 -march=native 编译;使用 numactl --cpunodebind=0 ... numactl --cpunodebind=0-3 执行 - 使用 CPU 绑定我们有以下发现:1 个 CPU(速度 x)、2 个 CPU(速度 ~ x/2)、3 个 CPU(速度~ x/3) [速度=越高越好]。所以我们看到的是性能随着 CPU 数量的增加而恶化。内存绑定、交错 (--interleave=all) 和 --localalloc 在这里不起作用(我们监控了所有 QPI 链接,并且每个链接的链接负载低于 1%)。

英特尔 TBB 论坛讨论:http: //software.intel.com/en-us/forums/topic/346334

0 投票
1 回答
3038 浏览

linux - qemu-kvm numa 拓扑暴露问题

我正在尝试实现以下场景。

我有一个带有 4 个 numa 节点的 linux 盒子,每个节点有 6 个 cpu。为了获得更好的 kvm 客户机性能,我将每个 vcpu 固定到一组 cpu,最好在同一个 numa 单元中。

例如,如果我想启动一个 12 核来宾,我将前 6 个 vcpus 固定到 NUMA 节点 1 中的 cpuset,将第二个 6 固定到 NUMA 节点 2 中的 cpuset。

到目前为止一切顺利,当我尝试将该拓扑暴露给来宾时问题开始出现,即让来宾知道它在 2 个 NUMA 节点上有两个 cpuset。

我认为,如果我使用-smp 12,sockets=2,cores=6,threads=1qemu-kvm 的选项,它很可能会将它们分成两半,将前 6 个分组在一个套接字中,将第二个 6 分组在另一个套接字中,并使用-numa选项在适当的 vcpus 上设置 2 个 numa 节点。所以我的问题如下:

  1. -numa选项会发挥作用吗?在文档中,据说它是用于 numa 模拟的。如果它是模拟的,那是否意味着它会损害性能?我需要的是一种对客人说的方式:“这些 cpus 在同一个 NUMA 节点上”(即使它们不是)。这是实现这一目标的方法吗?

  2. qemu(1.2.0)似乎有一个错误,并且拓扑暴露得很严重。当我将 CPU 拓扑设置为(例如)-smp 9,sockets=3,cores=3,threads=1时,出于某种奇怪的原因,在来宾内部,我看到它们(使用 lstopo)排列在三个插槽中,但第一个有 4 个核心,第二个有 4 个核心,第三个有 1 个核心(4|4|1)。我想,它将它们分成 2 的幂,而不是相等的。我也观察到了同样的行为sockets=2,cores=10sockets=2,cores=18,你的名字,总是不将它们分成两半,而是按 2 的幂(即 8|2 和 16|2 )。sockets=2,cores=8虽然工作正常(这是意料之中的)。有没有人经历过这样的事情?

0 投票
0 回答
718 浏览

c - libnuma - 数据类型问题

我将 libnuma 用于增强的 NUMA 感知分配器。如“numa 手册页”或 libnuma API 中所述,有些功能不起作用。准确地说,我在使用这些功能时遇到了问题:numa_get_run_node_mask()numa_node_to_cpus().
关于前者,阅读 API 和手册,它说它返回 a struct bitmask *,而编译器要求 a nodemask_t
后者应该需要两个参数,如 API 定义的那样,但编译器要求三个。如果我传递三个参数——在我在源代码定义中找到的这个声明之后:numa_node_to_cpus_v1(int node, unsigned long *buffer, int bufferlen)——我每次都会得到一个段错误,无论我使用什么 bufferlen

顺便提一下,后一个功能与您键入命令时numa_node_to_cpus()的用途相同:它用于检索节点中的所有cpu。我通读了源代码,它与两个参数一起正常工作。numactlnumactl --hardwareint node, struct bitmask *mask

也许有需要修复的错误,或者通过 libnuma 版本更改的 API 和源之间的一些差异。(顺便说一句,我如何检查机器上正在运行哪个 libnuma/numactl?我在服务器上远程工作,numactl似乎没有--version选项!)

0 投票
1 回答
1391 浏览

c - numa, mbind, 段错误

我已经使用 valloc 分配了内存,比方说 [15*sizeof(double)] 的数组 A。现在我把它分成三块,我想将每一块(长度为 5)绑定到三个 NUMA 节点(比如 0、1 和 2)。目前,我正在执行以下操作:

第一个问题是我做得对吗?例如,与页面大小正确对齐是否有任何问题?目前,数组 A 的大小为 15,它运行良好,但如果我将数组大小重置为 6156000 和piece=2052000,随后对 mbind 的三个调用以 &A[0]、&A[2052000] 和 &A[4104000 ] 然后我得到一个分段错误(有时它只是挂在那里)。为什么它适用于小尺寸但对于较大的尺寸会给我带来段错误?谢谢。

0 投票
1 回答
618 浏览

c - mbind 返回 EINVAL

我正在使用为以下问题提供的代码numa+mbind+segfault,每次调用 mbind 都会返回 EINVAL。我怎样才能得到完全错误的东西?我问这个是因为 EINVAL 可以出于多种原因返回。

运行程序后(通过在每次 mbind 调用之前将节点掩码分别更改为 1,2 和 4)如下所示(作为 Mats Petersson 的回答)。它有时会出现段错误,有时运行良好。当它出现段错误时,dmesg 如下:

0 投票
1 回答
3343 浏览

c - numactl --membind

在 Linux 中使用带有 --membind 选项的 numactl 时,假设我执行以下操作:

./prog 的内存是否会分配在所有 NUMA 节点 0、1 和 2 上?或者如果 NUMA 节点 0 的内存不够,内存会只分配在 NUMA 节点 1 和 2 上吗?谢谢。