所以这是代码:
#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
Run Code Online (Sandbox Code Playgroud)
现在来解释最新进展.在我的并行区域的开头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
}
}
Run Code Online (Sandbox Code Playgroud)
表示我想要通过一定数量的线程分配的一些工作,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的流量控制中看到了一个缺陷.
如果您查看OpenMP V3.0规范,2.5工作共享构造,请说明:
以下限制适用于工作共享构造:
- 每个工作共享区域必须由团队中的所有线程遇到或根本不遇到.
- 对于团队中的每个线程,遇到的工作共享区域和障碍区域的顺序必须相同.
通过在if中进行工作共享,您违反了这两个限制,使您的程序不符合要求.根据规范,不合格的OpenMP程序具有"未指定的"行为.
至于将使用哪些线程来执行for循环,调度类型为"static,1",第一个工作块 - 在这种情况下count = 0 - 将被分配给线程0.下一个块(count = 1)将被分配给线程1等,直到分配了所有块.如果有多个块而不是线程,那么赋值将以循环方式在线程0重新开始.您可以在OpenMP规范的2.5.1循环结构中阅读确切的措辞,在描述其中涉及schedule子句.