问题描述
朋友,我正在尝试学习openMP范例.我使用以下代码来了解#omp编译指示.
Friends, I am trying to learn the openMP paradigm.I used the following code to understand the #omp for pragma.
int main(void){
int tid;
int i;
omp_set_num_threads(5);
#pragma omp parallel \
private(tid)
{
tid=omp_get_thread_num();
printf("tid=%d started ...\n", tid);
fflush(stdout);
#pragma omp for
for(i=1; i<=20; i++){
printf("t%d - i%d \n",
omp_get_thread_num(), i);
fflush(stdout);
}
printf("tid=%d work done ...\n", tid);
}
return 0;
}
在上面的代码中,#pragma omp parallel的末尾有一个隐式屏障,这意味着所有线程0、1、2、3、4必须在到达下一条语句之前到达那里.
In the above code, there is an implicit barrier at the end of #pragma omp parallel, meaning all the threads 0,1,2,3,4 must reach there before going to the next statement.
因此,要检查此障碍,我在if(tid!= 0)条件下将此"pragma for"括起来,这意味着除线程0(即1,2,3,4)以外的所有线程都应在循环中完成其工作,并且无限期地等待thread0.但是,令我惊讶的是,这没有发生.每个线程都在进行迭代并成功完成.即t1完成迭代5,6,7,8 ---- t2完成9,10,11,12 ---- t3完成13,14,15,16,而t4完成17,18,19,20.请注意:迭代1,2,3,4从未完成.
So, to check this barrier, I enclosed this "pragma for" in a condition if(tid!=0), meaning all threads except thread 0 i.e 1,2,3,4 should complete their work in the loop and wait for thread0 indefinitely. But, to my surprise this is not happening. Every thread is doing its iteration and completing successfully. i.e t1 completes iterations 5,6,7,8 ---- t2 does 9,10,11,12 ---- t3 does 13,14,15,16 and t4 does 17,18,19,20. Please note : iteration 1,2,3,4 were never completed.
为了更深入地研究而不是tid!= 0,我在tid!= 1中包含了相同的#pragma,这意味着线程1绕过了屏障,而不是线程0.令我惊讶的是,该程序现在挂起,所有线程都在等待线程1.
To dig deeper, instead of tid!=0, I enclosed the same #pragma for in tid!=1 meaning instead of thread0, thread1 bypasses the barrier. To my surprise, the program now hangs and all threads wait for the thread1.
有人可以告诉我这种意外行为的解释吗?最终挂起的代码:
Can somebody please tell me the explanation for such unexpected behavior. Final code that hanged :
int main(void){
int tid;
int i;
omp_set_num_threads(5);
#pragma omp parallel \
private(tid)
{
tid=omp_get_thread_num();
printf("tid=%d started ...\n", tid);
fflush(stdout);
if(tid!=1){
/* worksharing */
#pragma omp for
for(i=1; i<=20; i++){
printf("t%d - i%d \n",
omp_get_thread_num(), i);
fflush(stdout);
}
}else{
printf("t1 reached here. \n");
}
printf("tid=%d work done ...\n", tid);
}
return 0;
}
我尝试设置共享或私有的,但是并没有改变程序的行为.
I tried setting i shared or private, but it did not change the behavior of the program.
推荐答案
此处的问题是该行为未由标准定义.从OpenMP 3.1的第2.5节第21行开始,规范(但文本保持不变,或者自开始以来较少):
The problem here is that the behaviour is undefined by the standard. From Section 2.5, line 21 of the OpenMP 3.1 specification (but the text has stayed the same more or less since the beginning):
omp for
是工作共享结构.所以是的,我通常也希望您的代码挂起,但是编译器有权假设您所做的事永远不会发生,因此最终结果-有时会挂起,但有时却没有,具体取决于细节在哪个线程上受阻-也许并不奇怪.
Where omp for
is a worksharing construct. So yes, I too would normally expect a hang with your code, but the compiler is entitled to assume that what you're doing never happens, and so the end result -- it sometimes hangs but sometimes doesn't, depending on the details on which threads you hold up -- maybe isn't that surprising.
这篇关于#pragma结尾的隐式屏障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!