我有一台双插槽 Xeon E5522 2.26GHZ 机器(禁用超线程)在支持 NUMA 的 linux 内核 3.0 上运行 ubuntu 服务器。架构布局是每个插槽 4 个物理内核。OpenMP 应用程序在这台机器上运行,我有以下问题:
在 NUMA 机器 + 感知内核上运行时,OpenMP 程序是否会自动利用(即线程及其私有数据在执行过程中保存在 numa 节点上)?如果没有,可以做什么?
NUMA 和每线程私有 C++ STL 数据结构怎么样?
我有一台双插槽 Xeon E5522 2.26GHZ 机器(禁用超线程)在支持 NUMA 的 linux 内核 3.0 上运行 ubuntu 服务器。架构布局是每个插槽 4 个物理内核。OpenMP 应用程序在这台机器上运行,我有以下问题:
在 NUMA 机器 + 感知内核上运行时,OpenMP 程序是否会自动利用(即线程及其私有数据在执行过程中保存在 numa 节点上)?如果没有,可以做什么?
NUMA 和每线程私有 C++ STL 数据结构怎么样?
当前的 OpenMP 标准定义了一个布尔环境变量OMP_PROC_BIND
,用于控制 OpenMP 线程的绑定。如果设置为true
,例如
shell$ OMP_PROC_BIND=true OMP_NUM_THREADS=12 ./app.x
那么 OpenMP 执行环境不应该在处理器之间移动线程。不幸的是,关于这些线程应该如何绑定没有更多的说明,而这正是 OpenMP 语言委员会的一个特殊工作组目前正在解决的问题。OpenMP 4.0 将附带新的环境变量和子句,允许人们指定如何分配线程。当然,许多 OpenMP 实现都提供了自己的非标准方法来控制绑定。
大多数 OpenMP 运行时仍然不支持 NUMA。他们很乐意将线程分派给任何可用的 CPU,您必须确保每个线程只访问属于它的数据。在这个方向上有一些一般性的提示:
dynamic
对并行for
(C/C++) / DO
(Fortran) 循环使用调度。for
如果您运行两个具有相同团队大小和相同迭代块数的单独并行循环,则static
两个循环的调度块 0 将由线程 0 执行,块 1 - 由线程 1 执行,依此类推。我的一些同事已经彻底评估了不同 OpenMP 运行时的 NUMA 行为,并专门研究了英特尔实施的 NUMA 意识,但文章尚未发布,因此我无法为您提供链接。
有一个名为ForestGOMP的研究项目,旨在为libgomp
. 也许你应该看看。
您还可以使用新工具来检查您的内存放置和访问是否正确,该工具用于分析 NUMA 应用程序,现在是 Linux 的开源工具:NUMAPROF:https ://memtt.github.io/numaprof/ 。