2012-07-12 117 views
0

我想在OpenMP的幫助下並行化這些代碼,例如 #pragma omp parallel for,以將工作分成不同的線程。與SETS一起使用openMP

什麼將是一種有效的方式?這裏level是在多個線程之間共享的。

這裏是一個集合。

for(iter=make.at(level).begin();iter!=make.at(level).end();iter++) 
{ 
    Function(*iter); 
} 

回答

2

如果make.at(level)返回的類型有持續訪問時間如果你的編譯器支持最新足夠的OpenMP版本隨機訪問迭代器(讀:這是 MSVC++),那麼你可以直接使用parallel for工作共享指令:

obj = make.at(level); 
#pragma omp parallel for 
for (iter = obj.begin(); iter != obj.end(); iter++) 
{ 
    Function(*iter); 
} 

如果該類型不提供拉多姆訪問迭代器,但仍然你的編譯器支持OpenMP的3.0或更新版本,那麼你可以使用OpenMP的任務:

#pragma omp parallel 
{ 
    #pragma omp single 
    { 
     obj = make.at(level); 
     for (iter = obj.begin(); iter != obj.end(); iter++) 
     { 
      #pragma omp task 
      Function(*iter); 
     } 
    } 
} 

這裏一個線程執行for循環並創建許多OpenMP任務。每項任務將使用相應的值*iterFunction()進行一次調用。然後,每個空閒線程將開始從未完成的任務列表中選取。在並行區域的末尾存在一個隱含的障礙,所以主線程將在繼續執行並行區域之前盡職地等待所有任務完成。

如果你不幸用微軟的Visual C++,那麼你就沒有多少選擇的餘地,而不是創建對象的指針數組,並使用一個簡單的整數循環迭代它:

obj = make.at(level); 
obj_type* elements = new obj_type*[obj.size()]; 
for (i = 0, iter = obj.begin(); i < obj.size(); i++) 
{ 
    elements[i] = &(*iter++); 
} 

#pragma omp parallel for 
for (i = 0; i < obj.size(); i++) 
{ 
    Function(*elements[i]); 
} 

delete [] elements; 

這不是最優雅的解決方案,但它應該工作。

編輯:如果我從你的問題的標題正確理解,你正在使用集合。這排除了第一個算法,因爲集合不支持隨機訪問迭代器。取決於編譯器對OpenMP任務的支持,使用第二種或第三種算法。

0

要使用使用OpenMP這個迭代器模式可能需要如何進行循環重新思考 - 你不能用#pragma omp for,因爲你的循環不是一個簡單的整數循環。我不知道下面將工作:

iter = make.at(level).begin(); 
end = make.at(level).end(); 

#pragma omp parallel private(iter) shared(make,level,end) 
{ 
    #pragma omp single 
    func(iter);      /* only one thread does the first item */ 

    while (1) 
    { 
     #pragma omp critical 
     iter = make.at(level).next(); /* each thread gets a different item */ 

     if (iter == end) 
      break; 

     func(iter); 
    } 
} /* end parallel block */ 

注意,我不得不改變你的iter++進入臨界區一個next()調用,使其工作。原因是共享的對象需要記住哪些項目已經被處理。