2016-01-23 95 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