为两个单独的任务声明不同的嵌套线程数(OpenMP)

时间:2016-07-20 19:37:09

标签: multithreading parallel-processing nested openmp

我正在编写一个在外层利用某些并行性的并行代码。基本上有两个可以同时执行的独立子程序(非常昂贵)。这是一个很大的代码,因此,在每个子程序中,还有其他调用以及许多omp parallel / do区域。所以为了执行我的两个子程序,我想利用嵌套的并行性,这样它们都可以在外部区域中调用:

!$omp parallel

    !$omp single
        ! Do the first expensive task (contains more omp parallel regions)
    !$omp end single nowait

    !$omp single
        ! Do the second expensive task (contains more omp parallel regions)
    !$omp end single nowait

!$omp end parallel

如果这些昂贵的任务都花费了相同的时间,我就不会有问题。但在模拟过程中,每个时间步,每个必须做的数量都会发生变化。所以做一个环境变量来设置嵌套的线程数,比如export OMP_NUM_THREADS=16,8,其中我在第一级并行中有16个,在嵌套区域中有8个(在两个昂贵的子程序中),效果不好。我有一个方案已经分配正确数量的线程到他们各自的任务,我只是不知道如何为相应的子程序中的嵌套级别设置不同数量的线程。当然,我可以进入每个昂贵的子程序和其中的所有子程序,并实际硬编码我想要的线程数,但就像我提到的这是一个非常大的代码,这是一个丑陋的解决方案。我更愿意以环境变量的方式来做这件事。在线没有关于此主题的信息。有没有人知道如何做到这一点?

提前致谢。

1 个答案:

答案 0 :(得分:0)

我不确定我是否正确理解您要实现的目标,但您可以通过调用omp_set_num_threads()来设置嵌套并行区域的默认团队规模。如果从应用程序的序列部分调用它,它将为顶级并行区域设置默认团队大小。如果从并行区域内调用它,它将影响由调用线程生成的嵌套并行区域。不同的线程可以为其嵌套区域设置不同的团队大小。因此,简而言之,您可以执行以下操作:

!$omp parallel

    !$omp single
        call omp_set_num_threads(nn)
        ! Do the first expensive task (contains more omp parallel regions)
    !$omp end single nowait

    !$omp single
        call omp_set_num_threads(mm)
        ! Do the second expensive task (contains more omp parallel regions)
    !$omp end single nowait

!$omp end parallel

从执行第一个单一构造的线程产生的并行区域将使用nn个线程执行。从执行第二个单一构造的线程产生的并行区域将使用mm个线程执行。

另外,您是否考虑过使用明确的OpenMP任务(!$omp task)而不是single + nowait