2012-06-13 42 views
3

我對OpenMP相當陌生,所以這可能有一個簡單的答案,但我一直無法找到它。OpenMP:鎖定對單個數組元素的訪問權限?

假設我有以下C代碼,並且想要使用OpenMP進行並行化。 A是一個具有小於1的double值的對象數組,是一個鏈表的數組,append將一個指針添加到鏈表的末尾。

#pragma omp for 
for (i = 0; i < n; ++i) { 
    x = (int) (A[i].val * NUM_BUCKETS); 
    append(&A[i], buckets[x]); 
} 

問題是,多個線程可能試圖將項目追加到給定的存儲桶一次。我可以讓這個附加語句至關重要。但是,在我的應用程序中,我可能會有大約1000個存儲桶,所以大多數時間線程將在不同的存儲桶上運行。

是否有強制鎖定桶的各個元素的方法?或者處理這個問題的其他方式?

回答

7

那麼,OpenMP不能自動爲你做,但它可以讓你創建自己的鎖變量,你可以使用它來限制對數組元素的訪問;例如,你可以有每個數組元素一個鎖:

#include <stdio.h> 
#include <omp.h> 


int main(int argc, char **argv) 
{ 
    const int NITEMS=20; 
    int array[NITEMS]; 
    omp_lock_t lock[NITEMS]; 

    for (int i=0; i<NITEMS; i++) 
     omp_init_lock(&(lock[i])); 

#pragma omp parallel for shared(array, lock) default(none) 
    for (int i=0; i<NITEMS; i++) { 
     int tid = omp_get_thread_num(); 
     int item = (i * 7) % NITEMS; 

     omp_set_lock(&(lock[item])); 
     array[item] = tid; // only one thread in here at a time; others block at set_lock() 
     omp_unset_lock(&(lock[item])); 
    } 

    for (int i=0; i<NITEMS; i++) 
     printf("%3d ", array[i]); 
    printf("\n"); 

    for (int i=0; i<NITEMS; i++) 
     omp_destroy_lock(&(lock[i])); 


    return 0; 
} 

或者,如果粒度的該級別比你需要的,你可以阻止陣列的區域等

+0

+1我完全忘了更關於OpenMP鎖定原語。 –

2

OpenMP不提供細粒度鎖定。你可以準備新的列表元素,例如通過將其next指針設置爲NULL並使用atomic來防止列表尾指針的更新。這與目前的OpenMP實現一樣好。

當然,由於OpenMP使用底層OS線程原語,所以可以使用後者提供的任何鎖定,例如,爲每個桶使用一組pthreads互斥量。缺點是它會創建不適合的應用程序,但如果效率更重要,您可能願意犧牲可移植性。