我正在学习omp并遇到这个问题...... 考虑以下代码:
(i) 数组 a、b 和 c 被初始化
#pragma omp parallel num_threads(4)
{
#pragma omp for schedule(static, 64)
for(int i = 0; i < 256; i++)
{
d[i] = a[i];
if( i + 1 < 256 )
d[i+1] = b[i];
if( i + 2 < 256 )
d[i+2] = c[i];
}
}
多次运行此代码时,注意到以下观察结果:
(i) 看到随机结果(正确/不正确) (ii) 将不正确的值分配给索引 i=64 或 i=128 处的“d”
考虑到分配的线程数量 (4) 和迭代次数 (256),我应用了块大小为 64 的 Schedule(static, 64)。我假设使用 static 进行调度将使线程按顺序运行。我什至在作业上应用了#pragma omp critical,但这不起作用,随机行为仍然存在。
您的
schedule(static, 64)
只告诉256次迭代应该以64为一组进行分配,但它并没有确定哪个线程将负责哪个迭代,并且它绝对不能保证线程将以任何固定顺序执行。我发现这两篇文章很好地解释了这一点:
所以,你有一个竞争条件。即使你添加了,你仍然会遇到竞争条件
if( i + 1 < 256 )
#pragma omp critical
d[i+1] = b[i];
if( i + 2 < 256 )
#pragma omp critical
d[i+2] = c[i];
这意味着一次只允许 1 个线程执行这 2 条指令之一。但考虑到执行迭代 69 的线程 1 在线上
d[i+1] = b[i];
上,执行迭代 68 的线程 2 在线上 d[i+2] = c[i];
上。仍然是比赛状态。