所以这是代码:
#pragma omp parallel private (myId)
{
set_affinity();
myId = omp_get_thread_num();
if (myId<myConstant)
{
#pragma omp for schedule(static,1)
for(count = 0; count < AnotherConstant; count++)
{
//Do stuff, everything runs as it should
}
}
#pragma omp barrier //all threads wait as they should
#pragma omp single
{
//everything in here is executed by one thread as it should be
}
#pragma omp barrier //this is the barrier in which threads run ahead
par_time(cc_time_tot, phi_time_tot, psi_time_tot);
#pragma omp barrier
}
//do more stuff
现在解释发生了什么。在我的并行区域的开头myId设置为private,以便每个线程都有正确的线程ID。 set_affinity()控制哪个线程在哪个核心上运行。我遇到的问题涉及#pragma omp for schedule(static,1)。
块:
if (myId<myConstant)
{
#pragma omp for schedule(static,1)
for(count = 0; count < AnotherConstant; count++)
{
//Do stuff, everything runs as it should
}
}
表示我想要通过一定数量的线程分配的一些工作,0到myConstant-1。在这些线程上,我想要均匀地(以调度(静态,1)的方式)分配循环的迭代。这一切都正确执行。
然后代码进入单个区域,其中的所有命令都按原样执行。但是说我将myConstant指定为2.然后,如果我使用3个或更多线程运行,则通过单个材料执行的所有内容都正确执行,但是ID为3或更大的线程不会等待单个内部的所有命令完成。
在单个函数中,调用一些函数来创建由所有线程执行的任务。 id为3或更大(通常为myConstant或更多)的线程继续执行,执行par_time(),而其他线程仍在执行由单个执行的函数创建的任务。 par_time()只为每个线程打印一些数据。
如果我注释掉pragma omp for schedule(static,1)并且只有一个线程执行for循环(例如将if语句改为if(myId == 0)),那么一切正常。所以我不确定为什么前面提到的线程会继续前进。
让我知道是否有任何令人困惑的事情,这是一个特定的问题。我正在寻找,看看是否有人在OMP的流量控制中看到了一个缺陷。
答案 0 :(得分:7)
如果查看OpenMP V3.0规范,2.5工作共享构造,请说明:
以下限制适用于 工作共享结构:
- 团队中的所有线程都必须遇到每个工作共享区域 或根本没有。
- 必须遵守工作共享区域和障碍区域的顺序 对于a中的每个线程都是一样的 队。
通过在if中使用工作共享,您违反了这两个限制,使您的程序不符合要求。根据规范,不符合要求的OpenMP程序具有“未指定”的行为。
对于将用于执行for循环的线程,使用调度类型“static,1”,第一个工作块 - 在这种情况下count = 0 - 将被分配给线程0.下一个块(count = 1)将被分配给线程1等,直到分配了所有块。如果有多个块而不是线程,那么赋值将以循环方式在线程0重新开始。您可以在OpenMP规范的2.5.1循环结构中阅读确切的措辞,在描述其中涉及schedule子句。