我想要寫一個函數,它如何以線程安全的方式實現每進程一次寫入openmp中的全局共享變量?
1是線程安全的,即工作正確是否從OpenMP並行區域內或不叫,
2進行一次單次處理(不:每個線程一次)寫入全局共享變量。
我最初的想法是使用master
或single
指令,但它們在嵌套並行中失敗。是否有失敗證明解決方案?
我想要寫一個函數,它如何以線程安全的方式實現每進程一次寫入openmp中的全局共享變量?
1是線程安全的,即工作正確是否從OpenMP並行區域內或不叫,
2進行一次單次處理(不:每個線程一次)寫入全局共享變量。
我最初的想法是使用master
或single
指令,但它們在嵌套並行中失敗。是否有失敗證明解決方案?
一個粗糙的方法是在OpenMP關鍵區域,在這裏你們都設置了「已設置」標誌和共享變量。當每個線程進入關鍵區域時,它會測試已設置的標誌,並且
更細粒度的方法是使用OpenMP鎖;你可以通過設置第一個線程鎖定其他線程不能,並使用它作爲你的標誌:
#include <stdio.h>
#include <omp.h>
void setonce_thread(omp_lock_t *l, int input, int *sharedvar) {
if (omp_test_lock(l)) {
printf("Set lock with %d\n", input);
*sharedvar = input;
} else {
printf("Could not set lock with %d\n", input);
}
}
void setonce_crit(int input, int *setflag, int *sharedvar) {
#pragma omp critical
{
if ((*setflag) == 0) {
(*setflag)++;
*sharedvar = input;
printf("Set in crit with %d\n", input);
} else {
printf("Could not set in crit with %d\n", input);
}
}
}
int main()
{
omp_lock_t lck;
int sharedvar1, sharedvar2;
int setflag = 0;
int input = 17;
omp_set_nested(1);
omp_set_num_threads(9);
omp_init_lock(&lck);
#pragma omp parallel shared(lck, sharedvar1, sharedvar2, setflag, input) default(none) num_threads(3)
{
#pragma omp for
for (int i=0; i<3; i++) {
#pragma omp parallel shared(lck, sharedvar1, sharedvar2, setflag, input) default(none)
{
#pragma omp for
for (int j=0; j<3; j++) {
int id=omp_get_thread_num();
setonce_thread(&lck, id, &sharedvar1);
setonce_crit(id, &setflag, &sharedvar2);
}
}
}
omp_unset_lock(&lck);
}
omp_destroy_lock(&lck);
printf("Shared Var 1 = %d\n", sharedvar1);
printf("Shared Var 2 = %d\n", sharedvar2);
printf("Set Flag = %d\n", setflag);
return 0;
}
如果只寫入每個進程一次,而不是每個線程一次,那麼您不需要任何同步,因爲沒有任何同步。只要做好寫保護。
我認爲OPs的問題是_how_安排每個進程只做一次。 – 2011-12-24 17:14:08