我试图并行化下面的代码。很容易看出aux
的值之间存在依赖关系,因为它们是在内部循环之后计算的,但是在内部循环中需要它们(注意在第一次迭代时j = 0) ,内循环内的代码不执行)。另一方面,mu值之间没有依赖关系,因为我们只更新mu[k]
,但其他计算所需的唯一值在mu[j]
,0 <= j < k
。
我的方法是将aux
的元素锁定,直到计算出来。一旦计算出aux
的给定值,就会释放该元素的锁定,并且每个线程都可以使用它。但是,使用此代码会发生死锁,我无法弄清楚原因。有人有任何提示吗?
由于
for (j = 0; j < k; ++j)
locks[j] = 0;
#pragma omp parallel for num_threads(N_THREADS) private(j, i)
for (j = 0; j < k; ++j)
{
vals[j] = (long)0;
for (i = 0; i < j; i++)
{
while(!locks[i]);
vals[j] += mu[j][i] * aux[i];
}
aux[j] = (s[j] - vals[j]);
locks[j] = 1;
mu[k][j] = aux[j] / c[j];
}
答案 0 :(得分:0)
未优化时是否也会挂起?
在优化代码中,gcc不会多次阅读locks[i]
,因此:
for (i = 0; i < j; i++) {
while(!locks[i]);
就像写作:
for (i = 0; i < j; i++) {
if( !locks[i] ) for(;;) {}
尝试添加一个屏障来强制gcc重新读取锁[i]:
#define pause() do { asm volatile("pause;":::"memory"); } while(0)
...
for (i = 0; i < j; i++) {
while(!locks[i]) pause();
HTH