OpenMP - 管理多个并行阻止调用

时间:2017-11-08 22:53:20

标签: c++ multithreading openmp

假设我有一个名为run()的函数的程序,这个函数会执行for loop并在其中做一些工作。

由于我想利用我的所有CPU核心,因此我使用OpenMP#pragma omp parallel for进行并行化。

现在,问题是这个run()函数是从几个线程调用的,当有大量线程同时调用run()时,我有一个巨大的性能损失,因为那里每个OpenMP threads pragma调用都会有很多parallel for

只是为了ilustrate,我有线程A和线程B,我的CPU有4个内核,线程A调用函数run(),它将创建4 OpenMP线程运行for loop

现在,同时,线程B也调用run(),这将生成更多4 OpenMP个线程,从而产生总共8个OpenMP个线程。 / p>

我的问题是,如果有某种方法可以与OpenMP进行平衡,在上面的示例中,OpenMP可以使用A的半个线程和B的一半。 另一个策略是OpenMP创建一个线程队列,因此它永远不会使用超过4个OpenMP个线程。

这样的事情可能吗?

PS。请注意,我的示例中的2个线程只是为了说明它,在我的程序中不清楚将调用多少线程run(),因为线程数是在运行时根据需要创建的。

PS 2.请注意,每当我谈论OpenMP创建的线程时,我都称它为OpenMP线程,当我谈论通过其他方式创建的线程时(例如std::thread我简单地称它为线程。

1 个答案:

答案 0 :(得分:0)

如果仅使用OpenMP进行并行操作,并且启用了nested parallelism,则可以使用num_threads的{​​{1}}参数指定使用一半的线程:

pragma omp parallel

即使您使用混合线程技术(这似乎是您的情况),您仍然可以通过使用不同的方法设置int const currentNumThreads = omp_get_num_threads(); int const maxNumThreads = omp_get_max_num_threads(); #pragma omp parallel for num_threads(maxNumThreads/currentNumThreads) for ( ... ) { ... } currentNumThreads来实现相同的目标。

但要谨慎。对于OpenMP,使用嵌套并行性通常是不可取的,因为它使代码非常fragile and rigid。对maxNumThreads函数的任何更改都需要知道调用它的位置,并且将来对run()的任何调用都需要了解其中的内容。在性能和维护方面,尝试遵循data parallel方法进行OpenMP使用是最好的。也就是说,在每个线程中执行一组类似的操作,但是在不同的数据块上执行。

例外情况是,如果您正在使用可以生成的OpenMP任务,并让调度程序处理它。在并行for循环中使用任务并行性将导致性能不佳,因为缺少data locality并且如果任务很小则开销很高。