我正在尝试创建一个OpenMP程序,它将按顺序迭代循环。我意识到线程并不适用于顺序程序 - 我试图比单个线程获得一点加速,或者至少保持执行时间类似于单线程程序。
在我的#pragma omp parallel section中,每个线程计算一个大数组的自己的部分,并得到该部分的总和。这些都可以并行运行。然后我希望线程按顺序运行,并将每个总和添加到TotalSum IN ORDER中。因此,线程1必须等待线程0完成,依此类推。我在#pragma omp critical部分中有这个部分。一切都运行正常,只有线程0正在完成,然后程序退出。如何确保其他线程将继续轮询?我尝试过sleep()和while循环,但是在线程0完成后它会继续退出。
我没有使用#pragma omp parallel,因为我需要跟踪每个线程访问的主数组的特定范围。以下是相关代码部分的缩短版本:
//DONE and MasterArray are global arrays. DONE keeps track of all the threads that have completed
int Function()
{
#pragma omp parallel
{
int ID = omp_get_thread_num
variables: start,end,i,j,temp(array) (all are initialized here)
j = 0;
for (i = start; i < end; i++)
{
if(i != start)
temp[j] = MasterArray[i];
else
temp[j] = temp[j-1] + MasterArray[i];
j++;
}
#pragma omp critical
{
while(DONE[ID] == 0 && ERROR == 0) {
int size = sizeof(temp) / sizeof(temp[0]);
if (ID == 0) {
Sum = temp[size];
DONE[ID] = 1;
if (some situation)
ERROR = 1; //there's an error and we need to exit the function and program
}
else if (DONE[ID-1] == 1) {
Sum = temp[size];
DONE[ID] = 1;
if (some situation)
ERROR = 1; //there's an error and we need to exit the function and program
}
}
}
}
if (ERROR == 1)
return(-1);
else
return(0);
}
在初始化线程数后,从main调用此函数。在我看来,并行部分完成,然后我们检查错误。如果发现错误,则循环终止。我意识到这里出了问题,但我无法弄清楚它是什么,现在我只是在圈子里。任何帮助都会很棒。同样,我的问题是只在线程0执行后函数退出,但没有标记错误。我也在pthreads中运行它,但执行起来更简单。 谢谢!
答案 0 :(得分:2)
您尝试使用#pragma omp critical
对线程进行排序是完全错误的。在任何时候,临界区中只能有一个线程,并且不确定线程到达临界区的顺序。所以在你的代码中,它可能发生在例如线程#2首先进入临界区,永远不会离开它,等待线程#1完成,而线程#1和其余线程在#pragma omp critical
等待。即使有些线程,例如线程#0很幸运地以正确的顺序完成关键部分,它们将在并行区域末尾的隐式屏障上等待。换句话说,这段代码几乎可以保证死锁。
我建议你做一些更简单自然的订购线程,即有序的部分。它应该是这样的:
#pragma omp parallel
{
int ID = omp_get_thread_num();
// Computations done by each thread
#pragma omp for ordered schedule(static,1)
for( int t=0; t<omp_get_num_threads(); ++t )
{
assert( t==ID );
#pragma omp ordered
{
// Do the stuff you want to be in order
}
}
}
因此,您创建一个并行循环,其迭代次数等于该区域中的线程数。 schedule(static,1)
子句明确表示迭代按线程ID的顺序分配给每个线程一个;并且ordered
子句允许在循环内使用有序部分。现在在循环体中放置一个有序部分(#pragma omp ordered
之后的块),它将按迭代顺序执行,这也是线程ID的顺序(由断言确保)。
有关详情,请查看以下问题:How does the omp ordered clause work?