2016-01-23 92 views
0

我正在尝试并行下面的代码。很容易看到aux的值之间存在依赖关系,因为它们是在内部循环之后计算的,但它们在内部循环内部是需要的(注意,在第一次迭代j = 0时,内部循环内的代码是未执行)。另一方面,由于我们只更新了mu[k],所以其他计算所需的唯一值在mu[j]之间,因此0 <= j < k的值不依赖于mu的值。并行循环上的死锁

我的方法是让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

是否还没有进行优化时挂? 在优化的代码,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