我有一个 OpenMP 并行化程序,如下所示:
[...]
#pragma omp parallel
{
//initialize threads
#pragma omp for
for(...)
{
//Work is done here
}
}
现在我正在添加 MPI 支持。我需要的是一个处理通信的线程,在我的例子中,它始终调用 GatherAll 并填充/清空链接列表以从其他进程接收/发送数据。该线程应该发送/接收,直到设置标志为止。所以现在示例中没有 MPI 内容,我的问题是关于 OpenMP 中该例程的实现。 我如何实现这样的线程?例如,我尝试在这里引入一个指令:
[...]
int kill=0
#pragma omp parallel shared(kill)
{
//initialize threads
#pragma omp single nowait
{
while(!kill)
send_receive();
}
#pragma omp for
for(...)
{
//Work is done here
}
kill=1
}
但在这种情况下,程序会卡住,因为 for 循环之后的隐式屏障会等待上面的 while 循环中的线程。
谢谢你,鲁格米尼。
最佳答案
您可以尝试将 nowait
子句添加到您的 single
构造中:
编辑:回复第一条评论
如果为 OpenMP 启用嵌套并行性,您也许可以通过进行两级并行性来实现您想要的目的。在顶层,有两个并发并行部分,一个用于 MPI 通信,另一个用于本地计算。最后一部分本身可以并行化,这为您提供了第二级并行化。只有执行该级别的线程才会受到其中的障碍的影响。
#include <iostream>
#include <omp.h>
int main()
{
int kill = 0;
#pragma omp parallel sections
{
#pragma omp section
{
while (kill == 0){
/* manage MPI communications */
}
}
#pragma omp section
{
#pragma omp parallel
#pragma omp for
for (int i = 0; i < 10000 ; ++i) {
/* your workload */
}
kill = 1;
}
}
}
但是,您必须意识到,如果没有至少两个线程,您的代码将会中断,这意味着您将打破代码的顺序版本和并行版本应该执行相同操作的假设。
将 OpenMP 内核包装在更全局的 MPI 通信方案中会更加清晰(可能使用异步通信来重叠通信与计算)。
关于multithreading - OpenMP 中进程间通信的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9685403/