C 如何使用OpenMP为单个omp中的omp嵌套omp

C 如何使用OpenMP为单个omp中的omp嵌套omp,c,openmp,parallel-processing,C,Openmp,Parallel Processing,我有一个for循环,我不想并行化,它调用一个我想并行化的函数(其中有一个for循环,我想并行化)。我想把并行区域放在整个批之外,这样我的线程只创建一次(以减少线程创建的开销) 但是,目前我有一个omp single覆盖for循环,它调用函数,并在函数内部有一个omp for来处理内部for循环。它的手,根据这是因为这样做是非法的 如果我不能那样做,我该怎么做?我想确保只有一个线程运行外部for循环并调用函数,但在函数内部我可以获得完全的并行性 这可能吗?有什么想法吗?关于: -将您的内部循环置于

我有一个for循环,我不想并行化,它调用一个我想并行化的函数(其中有一个for循环,我想并行化)。我想把并行区域放在整个批之外,这样我的线程只创建一次(以减少线程创建的开销)

但是,目前我有一个
omp single
覆盖for循环,它调用函数,并在函数内部有一个
omp for
来处理内部for循环。它的手,根据这是因为这样做是非法的

如果我不能那样做,我该怎么做?我想确保只有一个线程运行外部for循环并调用函数,但在函数内部我可以获得完全的并行性

这可能吗?有什么想法吗?

关于: -将您的内部循环置于#pragma omp并行模式中 -在外循环之前将活动线程数设置为1 -在调用其他函数之前,将其设置回N -将#pragma omp for放入函数内部

?


在OMP中,并行部分在函数边界上是暂时的,设置活动线程的数量不应该太有害。但是需要进行测试/基准测试。

大多数实现只创建一次线程-无论是在程序启动时还是在遇到第一个并行区域时。一旦创建,它们通常不会被销毁,而是在遇到并行结束区域时放入空闲线程池(由OpenMP实现处理)。这意味着您应该能够将并行区域放在循环中,而不必在每次遇到并行区域时都有线程创建开销。每次遇到并行区域时都会有一些小的开销,但比创建线程时要小得多。

您知道线程创建开销确实是个问题吗?好的OpenMP实现可能会很关心这一点,在没有并行区域处于活动状态时将一些线程保留在内部。我不确定我使用的是什么OpenMP实现(如果有帮助的话,我使用的是GCC 4.3.3),但我不确定它是否做到了这一点。当我在函数中有一个被多次调用的并行区域时,我的速度似乎会明显减慢(与加速相反),因此这表明我的实现可能没有做到这一点。你可以很容易地检查这一点,方法是让每个线程在并行区域的开头打印它的
pthread\u self()
值,检查线程是否被重用或重新创建。@Alexey-谢谢。我已经试过了,看起来这些线程正在被重复使用。我现在只是有点困惑为什么我的代码实际上运行得比较慢…但我想这是一个不同的问题!在并行区域启动后,无法更改执行该区域的线程数。从规范中可以看出:“一旦创建了团队,团队中的线程数量在该并行区域的持续时间内保持不变。”这就是我在发送此消息后所担心的。Thansk for the head up Alexey谢谢@Alexey-这可能就是为什么我尝试实现它时它没有起作用!那很有趣。在我的并行编程课程中,有人警告我们不要继续使用新的并行区域,因为这样做会耗费大量的开销时间。我曾尝试在内部函数中使用
#pragma omp parallel for
,但与串行运行相比,代码以这种方式运行(使用4个线程)要慢得多。关于我如何才能做到这一点,还有其他想法吗?一般来说,我同意你所学到的。不幸的是,OpenMP模型有一些限制。您可以使用嵌套并行来完成这项工作,但那会更糟。如果内部循环中的工作独立于上一次迭代,那么您可能可以使用任务。除此之外,在没有看到更多你想要做的事情的情况下,我已经没有想法了。@robintw,你可以做一些实验来看看是什么导致了减速。例如,尝试将并行区域的线程数设置为1。这样,OpenMP的开销应该非常小,并且程序应该比串行的慢一点。如果速度慢得多,那么原因可能不同于并行的开销。