OpenMP 的线程均匀分布机制

OpenMP's mechanism for spreading threads out evenly

OpenMP 尝试尽可能均匀地在内核中分布线程,但它是如何工作的?

最终,OS 正在决定如何传播它们。 OpenMP 是否只是建议 OS 这样做(类似于在 C 中使用 likely 宏或 register 关键字)。

如果我们运行在具有 num_cores 个内核的机器上使用 num_threads 个线程执行作业,其中 none 个当前正在使用,这是否公平假设线程将均匀分布在所有内核上(并假设 num_threads <= num_cores,您具有纯并行性),因为 OS 应该符合我们的最大利益并很好地分散负载。

我看到 x 轴是 # 个核心的强缩放图。那么我们是否假设他们用于 运行 作业的最大线程数 <= 内核数并且内核相对空闲?

或者所有这些都是有争议的问题。

OpenMP 线程在机器的核心 and/or 硬件线程上的调度主要由操作系统负责。它将根据自己的启发式决定何时何地开始/停止/迁移它们...

但是,OpenMP 为您提供了一些工具来指导/限制 OS 做出决定时的选择范围。例如,您可以访问:

  • 在并行区域启动的 OpenMP 线程数:OMP_NUM_THREADS 环境变量,num_threads 子句,omp_set_num_threads() 函数
  • OS 可以调度线程的逻辑核心:OMP_PLACES 环境变量。
  • 线程的可选固定策略:OMP_PROC_BIND 环境变量,proc_bind 子句。

这样,您就可以在一定程度上控制 OS 决策,但最终,它仍然控制着实际的日程安排。并且它将做出的决定并不总是您所想的(尤其是当您不使用放置或绑定时),因为机器工作负载和它应用的全局调度策略可能会干扰您认为对您的代码来说是最佳的.例如,在 NUMA(非统一内存访问)机器上,各种节点上使用的内存以及哪个内存段属于哪个进程等因素可能会阻止看似均匀的跨芯片线程分布,从而导致 CPU 本地争用...