Parallel processing #pragma结尾处的隐式障碍
朋友们,我正在努力学习openMP范例。 我使用以下代码来理解pragma的#ompParallel processing #pragma结尾处的隐式障碍,parallel-processing,openmp,openmpi,Parallel Processing,Openmp,Openmpi,朋友们,我正在努力学习openMP范例。 我使用以下代码来理解pragma的#omp 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
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;
int main(无效){
国际贸易署;
int i;
omp_设置_数量_线程(5);
#pragma-omp并行\
私营机构(工贸署)
{
tid=omp_get_thread_num();
printf(“tid=%d已开始…\n”,tid);
fflush(stdout);
#pragma omp for
对于(i=1;i而言,这里的问题是该行为未被标准定义。从OpenMP 3.1第2.5节第21行(但文本自开始以来或多或少保持不变):
•团队中的所有线程都必须遇到每个工作共享区域
或者根本没有
其中,omp for
是一个工作共享结构。因此,是的,我通常也希望代码挂起,但编译器有权假设您所做的事情永远不会发生,因此最终结果——它有时挂起,但有时不挂起,这取决于您挂起的线程的详细信息——可能并不奇怪 #pragma omp for提供了一种使用“nowait”关键字消除循环末尾隐式障碍的方法,但我没有使用它。1)i
需要是私有的。2)omp for
作为一个工作共享构造,在已经存在的线程上共享工作。由于线程1挂起以执行工作共享for循环,因此您会阻塞自己。请参阅检查主线程和工作线程等类似的线程更像是mpi或pthread样式。openmp背后的思想就是摆脱主线程和其他线程之间的所有这些烦躁不安。当然可以这样做,但您可能希望在不同线程之间分离任务,而不是区分不同的任务。@Bort:即使我在实际解决问题时也不想这样编码,但我对openmp的实现感到困惑。我又执行了一次检查,以查看程序是否如果进入循环的线程数之间存在间隙,即0,2,3,4,am将挂起。因此,我将该条件替换为if(tid==1 | | tid==4 | | tid==5)。但是程序现在没有挂起。因此,主线程有一些特殊的地方我在这里无法理解。感谢链接。即使我知道这有未定义的行为,但仍然继续了解openMP库的实际实现。我从中了解到:“每个并行块只实现一个屏障。因此,从一个线程到另一个线程的信令可以跨同一并行块中的不同屏障工作。”希望:我从中了解到:
我以后不会使用未定义的行为,因为它会导致各种意外行为。
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;