OpenMP并行现在等待

OpenMP parallel nowait

本文关键字:在等待 并行 OpenMP      更新时间:2023-10-16

OpenMP有办法移除parallel块上的屏障吗?

我知道nowait可以在parallel内的forsections块中使用,以便允许线程继续前进,而不必等待所有线程完成相关块。但是,#pragma omp parallel nowait会生成编译器错误。

我正在开发一个带有用户界面的程序。我调用一个函数来加载UI,在这种情况下,我还想与服务器联系,发送一些使用数据。

这些函数中的每一个都运行良好,但如果我不并行执行它们,则需要一段时间。如果服务器关闭,那么连接尝试可能需要几秒钟才能中止,然后简单地加载UI也需要一秒钟,此时时间太长了。首先加载UI,然后进行连接会使UI看起来冻结。

所以我想做一些类似的事情

// this generates a compiler error
#pragma omp parallel num_threads(2) nowait
{
if(omp_get_thread_num() == 0)
LoadUI();
else
Connect();
}

这样,主线程(必须是加载UI的线程)将加载UI,然后继续前进,而不考虑任何连接问题。然而,由于parallel nowait是被禁止的,我的理解是,如果由于parallel末尾的隐式屏障而出现连接问题(中止所需时间比加载UI所需时间更长),程序仍然会暂时挂起。

有办法绕过这个吗?我真正想做的是请求一个新线程在程序进行时进行连接,而不管线程做什么或需要多长时间才能完成(显然,线程不会接触主线程使用的任何数据)。

我认为您尝试做的与OpenMP fork-join模型不兼容。其想法是,在每个平行区域中,您生成在平行区域末端连接的线程。好吧,线程实际上并不是派生的,因为通常有一个线程池,但这是概念模型。

请注意,即使是以下情况也会产生编译器错误:

#pragma omp parallel for nowait
for (i=0; i<10; i++) {
...
}

你可以做的是避开for之后的屏障,平行区域内。例如:

#pragma omp parallel
{
#pragma omp parallel for
for (int i=0; i<2; i++) {
}
/* no wait here */
#pragma omp for
for (int i=0; i<2; i++) {
}
}

要做您需要的事情,您可能必须使用pthreads或线程库。

PS:你可以使用OpenMP部分,而不是检查线程id。