您可以将特定线程 ID 分组到 OpenMP 中的唯一任务组中吗?

Posted

技术标签:

【中文标题】您可以将特定线程 ID 分组到 OpenMP 中的唯一任务组中吗?【英文标题】:Can you group specific thread id's into unique task groups in OpenMP? 【发布时间】:2017-03-20 12:46:27 【问题描述】:

在运行我的程序之前,我会这样做:

export KMP_AFFINITY=explicit,proclist=[0-47],granularity=fine

然后我生成 48 个线程:

#pragma omp parallel num_threads(48) 

  int id = omp_get_thread_num();

并行结构中的每个线程现在都有一个与处理器 ID 匹配的 ID。

现在……

处理器 0 和处理器 24 实际上在同一个内核上。处理器 24 到 47 具有 0 到 23 的超线程。

我有一个线程正在使用的工作对象向量。他们根据自己的 id 从向量中挑选一个对象。

我正在尝试让 0/24、1/25、2/26 等...超线程内核在特定的“工作者”对象上配对,然后在对象中使用任务组:

class Worker 
public:
  int wId;
  Worker(int i) 
    wId = i;
  
  void doWork() 
    // Can I make a task group for the 2 threads reaching this code together?
    // will barriers, taskgroups, critical pragmas wait for all 48 threads?
  
;

int main() 
  vector<Worker> workers;
  for (int i = 0; i < 48; ++i) 
     Worker w(i);
     workers.push_back(w);
  
  #pragma omp parallel num_threads(48) 
  
    int id = omp_get_thread_num();
    workers[id % 24].doWork();
  

我不确定这样的事情是否可行。我的假设是,在 doWork() 函数中对 taskgroupbarriercritical 编译指示的任何使用都会影响所有 48 个线程,而不仅仅是应该共享对象的 2 个线程。

这是真的吗?如何创建一组已知处理器绑定的线程(即将线程 0 和线程 23 放入一个组)来做我想做的事?

【问题讨论】:

您是否考虑过嵌套并行,第一级 24 个线程(附加到核心)和第二级 2 个线程(将使用同一核心的 2 个超线程)? @Gilles -- 是的,这是我现在正在尝试测试的东西,但我不知道如何将 0/24、1/25 等对固定到同一个核心那种方案。我知道这需要更改 KMP_AFFINITYnum_threads 参数,但我不确定将这些设置为什么 【参考方案1】:

对于任何感兴趣的人......正如@Gilles 指出的那样,解决方案是嵌套。诀窍是正确导出:

export OMP_NESTED=1
export OMP_MAX_ACTIVE_LEVELS=2
export KMP_HOT_TEAMS=1
export KMP_HOT_TEAMS_MAX_LEVEL=2
export OMP_PROC_BIND=spread,spread
export OMP_PLACES=cores

然后你就可以这样做了:

#pragma omp num_thread(24) 
  #pragma omp num_thread(2) 
    // paired hyperthread code
  

(来源:https://software.intel.com/en-us/articles/process-and-thread-affinity-for-intel-xeon-phi-processors-x200)

【讨论】:

以上是关于您可以将特定线程 ID 分组到 OpenMP 中的唯一任务组中吗?的主要内容,如果未能解决你的问题,请参考以下文章

OpenMP C++ 中的线程

我可以将多个线程分配给 OpenMP 中的代码段吗?

如何不等待 OpenMP 中的其他线程?

将 OpenMP 应用于 C++ 中的特定嵌套循环

使用 openmp 时运行的线程数不一致

在openmp中使用不同线程组装矢量时缩放不良