2

我对同一 python 命令的多次启动如何绑定到 NUMA Xeon 机器上的内核感到困惑。

我读到OMP_NUM_THREADSenv var 设置了为numactl进程启动的线程数。因此,如果我在超线程 HT 机器上运行numactl --physcpubind=4-7 --membind=0 python -u test.pyOMP_NUM_THREADS=4下面的 lscpu 输出),它会将这个 numactl 进程限制为 4 个线程。但是由于机器有 HT,我不清楚4-7上面是 4 个物理还是 4 个逻辑。

  • 如何找到其中的哪些 numa-node-0 核心0-23,96-119是物理的,哪些是逻辑的?都是96-119合乎逻辑的还是穿插的?

  • 如果4-7都是物理内核,那么在启用 HT 的情况下,将只需要 2 个物理内核,那么另外 2 个会发生什么?

  • 在将线程绑定到物理内核时,OpenMP 库在哪里被调用?

(根据我有限的理解,我可以使用不同的 numactl 绑定python main.pyshshell 中启动命令 20 次,并且 OMP_NUM_THREADS 仍然适用,即使我没有在任何地方明确使用 MPI lib,对吗?)

Architecture:                    x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   46 bits physical, 48 bits virtual
CPU(s):                          192
On-line CPU(s) list:             0-191
Thread(s) per core:              2
Core(s) per socket:              48
Socket(s):                       2
NUMA node(s):                    4
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           85
Model name:                      Intel(R) Xeon(R) Platinum 9242 CPU @ 2.30GHz
Stepping:                        7
Frequency boost:                 enabled
CPU MHz:                         1000.026
CPU max MHz:                     2301,0000
CPU min MHz:                     1000,0000
BogoMIPS:                        4600.00
L1d cache:                       3 MiB
L1i cache:                       3 MiB
L2 cache:                        96 MiB
L3 cache:                        143 MiB
NUMA node0 CPU(s):               0-23,96-119
NUMA node1 CPU(s):               24-47,120-143
NUMA node2 CPU(s):               48-71,144-167
NUMA node3 CPU(s):               72-95,168-191
4

1 回答 1

1

我读到 OMP_NUM_THREADS env var 设置了为 numactl 进程启动的线程数。

numactl不要启动线程。它控制进程或共享内存的 NUMA 策略。但是,OpenMP 运行时可能会根据设置的环境调整区域创建的线程数numactl(尽管 AFAIK 标准未定义此行为)。您应该使用环境变量OMP_NUM_THREADS来设置线程数。您可以使用环境变量检查 OpenMP 配置OMP_DISPLAY_ENV

如何找到 0-23,96-119 中的 numa-node-0 内核中哪些是物理的,哪些是逻辑的?96-119 都是合乎逻辑的还是穿插的?

这有点复杂。物理 ID 是/proc/cpuinfo. 它们不能保证随着时间的推移保持不变(例如,它们可以在机器重新启动时改变),也不能保证“直观”(即遵循规则,例如彼此靠近的线程/内核是连续的)。应该避免手动对它们进行硬编码。例如,BIOS 更新或内核更新可能会导致以不同的顺序枚举逻辑内核。

您可以使用出色的工具hwloc将定义明确的确定性逻辑 ID 转换为物理 ID。在这里,您不能完全确定 0 和 96 是共享同一个内核的两个线程(尽管这对于您的处理器来说可能是正确的,看起来内核从每个物理内核中枚举了一个逻辑内核作为内核 0..95,然后每个物理核心上的另一个逻辑核心为 96..191)。另一种常见的可能性是 Linux 连续做每个物理核心的两个逻辑核心,使逻辑核心 2n 和 2n+1 共享一个物理核心。

如果 4-7 都是物理核心,那么在启用 HT 的情况下,将只需要 2 个物理核心,那么另外 2 个会发生什么?

--physcpubindofnumctl接受物理 cpu 编号,如有关文档的“处理器”字段中所示。因此,这里应该解释为物理线程ID。两个线程 ID 可以引用同一个物理内核(在启用超线程的 Intel 处理器上总是如此)。/proc/cpuinfo4-7

在将线程绑定到物理内核时,OpenMP 库在哪里被调用?

AFAIK,这是依赖于使用的 OpenMP 运行时的实现(例如 GOMP、IOMP 等)。当遇到第一个并行部分时,OpenMP 运行时的初始化通常会延迟完成。对于绑定,一些运行时/proc/cpuinfo手动读取,而另一些使用hwloc. 如果您想要确定性绑定,那么您应该使用OMP_PLACESOMP_PROC_BIND环境变量来告诉运行时使用自定义的用户定义方法而不是默认方法来绑定线程。


如果您想要安全和便携,请使用以下配置(使用 Bash):

OMP_NUM_THREADS=4
OMP_PROC_BIND=TRUE
OMP_PLACES={$(hwloc-calc --physical-output --sep "},{" --intersect PU core:all.pu:0)}

OpenMP 线程将安排在 OpenMP 位置。上述配置配置了 OpenMP 运行时,以便在 4 个不同的固定内核上静态映射 4 个线程。

于 2021-05-26T19:36:47.177 回答