2013-02-18 43 views
2

鑑於此代碼示例的練習是並行使用OpenMP的代碼使用任務。這是一組項目,我們想要數那些好的。 OpenMP:任務中的競態條件

int count_good (item_t* item) 
{ 
    int n = 0; 
    while (item) { 
     if (is_good(item)) 
      n++; 
     item = item->next; 
    } 
    return n; 
} 

這不完全是家庭作業。這是爲了完成考試。我的想法是這樣的:

int count_good (item_t* item) 
{ 
    int n = 0; 
    while (item) { 
     #pragma omp task 
     { 
     if (is_good(item)) 
      n++; 
     } 
     item = item->next; 
    } 
    #pragma omp taskwait 
    return n; 
} 
... 

int main() 
{ 
... 
#pragma omp parallel 
{ 
#pragma omp single 
    count_good(some_times); 
} 
} 

的問題是n是單線程的私有變量,但它可以在同一時間將增加不同的任務。這可能會產生競爭狀態嗎? #pragma omp critical可以避免嗎?

回答

1

你將不得不顯式聲明nshared,否則這將是firstprivate默認情況下(因爲它是隱含private在封閉的情況下)。然後爲了確保n的原子增量,應該應用atomic update構造。到底你的代碼應該是這樣的:

int count_good (item_t* item) 
{ 
    int n = 0; 
    while (item) { 
     #pragma omp task shared(n) 
     { 
     if (is_good(item)) 
      #pragma omp atomic update 
      n++; 
     } 
     item = item->next; 
    } 
    #pragma omp taskwait 
    return n; 
} 

critical結構具有比原子增量更高的開銷,至少在x86。

1

您可以使用reduction來計算「好」項目。以下代碼將爲您完成這項工作。您可能需要閱讀this for reductionthis for traversing linked list

int nCount = 0; 
#pragma omp parallel reduction(+ : nCount) 
{  
    for(struct item_t *listWalk = some_items; listWalk != NULL; 
     listWalk = listWalk->next) 
    { 
     #pragma omp single nowait 
     { 
      if(isGood(listWalk)){ 
      nCount += 1; 
      } 
     }   
    } 
}