查看此处的文档,以下结构已明确定义:
#pragma omp parallel //Line 1
{
#pragma omp for nowait //Line 3
for (i=0; i<N; i++)
a[i] = // some expression
#pragma omp for //Line 6
for (i=0; i<N; i++)
b[i] = ...... a[i] ......
}
Run Code Online (Sandbox Code Playgroud)
以来
这里的nowait子句意味着线程可以在第二个循环上启动,而其他线程仍然在第一个循环上工作.由于这两个循环在这里使用相同的调度,因此使用[i]的迭代确实可以依赖于已经计算了该值的迭代.
我很难理解为什么会这样.假设Line 3是:
#pragma omp for
然后,由于之前存在隐式屏障Line 6,下一个for循环将在a完全计算的所有索引处具有值.但是,随着no wait中Line 3,将如何运作?
假设,Line 1触发4个线程,t1, t2, t3并且t4.假设N是8并且第一个for循环中的索引分区是:
t1: 0, 4
t2: 1, 5
t3: 2, 6
t4: 3, 7
Run Code Online (Sandbox Code Playgroud)
假设t1完成索引0并4首先登陆Line 6现在到底发生了什么?它是如何保证它现在得到在同一指数运行0和4,为其a值由它在先前的迭代计算正确?如果第二个for循环访问a[i+1]怎么办?
你引用的材料是错误的.如果添加schedule(static)到两个循环,它就会变得正确- 这保证了连续循环的线程之间的索引分布相同.默认计划是实现定义的,您不能认为它是static.引用标准:
具有相同调度和迭代计数的不同循环区域,即使它们出现在相同的并行区域中,也可以不同地在线程之间分配迭代.唯一的例外是表2.5中指定的静态调度.依赖于哪个线程在任何其他情况下执行特定迭代的程序是不符合的.
如果第二个for循环访问a[i+1]你必须绝对留下障碍.
| 归档时间: |
|
| 查看次数: |
414 次 |
| 最近记录: |