首页 > 解决方案 > 在 OpenMP 并行区域内设置关联

问题描述

我正在尝试查看是否可以使用 pthread_setaffinity_np() 调用在 OpenMP 区域内设置亲和力,假设底层实现为 OpenMP 工作人员使用 pthread。在下面的示例代码中,对设置关联性的调用不会返回错误,并且 sched_getcpu() 调用还确认已正确设置核心关联性。但是,与使用 GOMP_CPU_AFFINITY 环境变量设置亲和性相比,这种设置亲和性的方式会导致相当大的性能下降,这表明使用 pthread_setaffinity_np() 存在一些潜在问题。在 OpenMP 区域内使用 pthread_setaffinity_np() 是否存在任何已知问题?对于我的用例,我需要使用“主人”的 pthread

#pragma omp parallel for reduction(+:sum) num_threads(num_drones)
  for (int i=start_N;i<end_N;i++){
    if(set[omp_get_thread_num()] == 0) {
      set[omp_get_thread_num()] = 1;
      cpu_set_t cpuset;
      CPU_ZERO(&cpuset);
      CPU_SET(rank*num_drones+omp_get_thread_num(), &cpuset);

      int error = pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);
      if (error != 0) {
        cout<< "\nError setting affinity";
        abort();
      }
    } else if (set[omp_get_thread_num()] == 1){
      set[omp_get_thread_num()] = 2;
      assert(rank*num_drones+omp_get_thread_num() == sched_getcpu());
    }
    sum += v1[i];
  }

标签: c++openmp

解决方案


这是个主意。OpenMP 运行时几乎肯定会根据它已建立的线程的亲和性来优化其内部算法和数据结构。(例如,使用分层屏障来最小化跨缓存和跨套接字通信)。你在上面盖章。

你说

我需要使用作为“主”的 pthread,每个 pthread 都将调用自己的 OpenMP 区域,并且需要为各自的 OpenMP 区域显式设置关联性。

但是你还没有说你为什么认为你需要这样做。

这感觉就像一个经典的“我有一个问题我不会向你解释,但这是我的解决方案不起作用,所以请为我解决这个解决方案”问题。

如果您要解释您的真正问题,我们可能会提供更多帮助...

(特别是,使用 OpenMP 的机制明智地选择线程亲和性可能就是您所需要的。请参阅控制 OpenMP 线程亲和性)。


推荐阅读