我想在OpenMP的幫助下並行化這些代碼,例如 #pragma omp parallel for
,以將工作分成不同的線程。與SETS一起使用openMP
什麼將是一種有效的方式?這裏level是在多個線程之間共享的。
這裏是一個集合。
for(iter=make.at(level).begin();iter!=make.at(level).end();iter++)
{
Function(*iter);
}
我想在OpenMP的幫助下並行化這些代碼,例如 #pragma omp parallel for
,以將工作分成不同的線程。與SETS一起使用openMP
什麼將是一種有效的方式?這裏level是在多個線程之間共享的。
這裏是一個集合。
for(iter=make.at(level).begin();iter!=make.at(level).end();iter++)
{
Function(*iter);
}
如果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任務。每項任務將使用相應的值*iter
對Function()
進行一次調用。然後,每個空閒線程將開始從未完成的任務列表中選取。在並行區域的末尾存在一個隱含的障礙,所以主線程將在繼續執行並行區域之前盡職地等待所有任務完成。
如果你不幸用微軟的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任務的支持,使用第二種或第三種算法。
似乎並行中的變量必須爲int。但我不確定。這是一個關於這個的話題。 Why must loop variables be signed in a parallel for?
要使用使用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()
調用,使其工作。原因是共享的對象需要記住哪些項目已經被處理。