OpenMP:获取正在运行的线程总数

时间:2011-01-16 16:19:04

标签: c++ parallel-processing openmp

我需要知道我的应用程序通过OpenMP生成的线程总数。不幸的是,omp_get_num_threads()函数在这里工作,因为它只产生当前团队中的线程数。

然而,我的代码以递归方式运行(基本上是分而治之),只要仍然有空闲的处理器,我想生成新的线程,但不多了。

有没有办法绕过omp_get_num_threads的限制并获取个正在运行的线程数?

如果需要更多细节,请考虑以下伪代码,这些代码非常接近地模拟我的工作流程:

function divide_and_conquer(Job job, int total_num_threads):
  if job.is_leaf(): # Recurrence base case.
    job.process()
    return

  left, right = job.divide()

  current_num_threads = omp_get_num_threads()
  if current_num_threads < total_num_threads: # (1)
    #pragma omp parallel num_threads(2)
      #pragma omp section
        divide_and_conquer(left, total_num_threads)
      #pragma omp section
        divide_and_conquer(right, total_num_threads)

  else:
    divide_and_conquer(left, total_num_threads)
    divide_and_conquer(right, total_num_threads)

  job = merge(left, right)

如果我将此代码称为total_num_threads值为4,则使用(1)注释的条件将始终评估为true(因为每个线程团队将最多包含两个线程)因此代码将始终生成两个新线程,无论有多少线程已经在更高级别运行。

我正在搜索独立于平台的方法来确定当前在我的应用程序中运行的线程总数。

3 个答案:

答案 0 :(得分:4)

我认为至少在OpenMP 3中没有任何这样的例程;如果有,我不确定它会有所帮助,因为在计算线程数和分叉之间显然存在巨大的竞争条件。如果每个人都看到剩下一个线程的余地,然后每个人都产生一个线程,你最终可能会将你的目标线程数超过2倍。

如果这确实是你的程序的结构,并且你只想限制线程的总数,那么有一些选项(所有这些都是OpenMP 3.0):

  1. 使用OMP_THREAD_LIMIT环境变量来限制OpenMP线程的总数
  2. 使用OMP_MAX_ACTIVE_LEVELSomp_set_max_active_levels()或针对omp_get_level()进行测试,以限制线程的嵌套程度;如果你只想要16个线程,则限制为4个嵌套级别
  3. 如果你想要比2的权力更精细的控制,你可以使用omp_get_level()找到你的等级,并在各个级别调用omp_get_ancestor_thread_num(int level)以找出你的父母,祖父母等等的线程(使用这个简单的左右分叉)确定全局线程ID。 (我认为在这种情况下它会像Σ l = 0..L-1 a l 2 Ll 其中l是水平数字从0开始,a是该级别的祖先线程数)。这会让你(比方说)允许线程0-3分叉而不是4-7,这样你最终会得到12个而不是16个线程。我认为这只适用于这种常规情况;如果每个父线程分叉了不同数量的子线程,我认为你不能确定一个唯一的全局线程ID,因为看起来你只能查询你的直接祖先。

答案 1 :(得分:2)

您所显示的代码存在一个问题,即“omp部分”必须位于“omp部分”的词法范围内。我假设你的意思是“omp parallel”是一个“omp parallel sections”。另一种方法是使用“omp任务”,然后你不必计算线程数。您只需将线程分配给并行区域,并允许OpenMP实现将任务分配给线程。

答案 2 :(得分:0)

考虑到你知道正在创建的线程的确切数量,我提出的最简单的解决方案就是保持自己的线程计数器。

请注意,我对OpenMP一无所知,因为我从未真正使用它。