[英]openmp ordering critical sections
我正在嘗試創建一個OpenMP程序,該程序將依次循環遍歷。 我意識到線程不是用於順序程序的-我正在嘗試與單線程相比略有加速,或者至少使執行時間與單線程程序相似。
在我的#pragma omp並行部分中,每個線程都會計算自己的大型數組部分,並獲取該部分的總和。 這些都可以並行運行。 然后,我希望線程按順序運行,並將每個總和添加到TotalSum IN ORDER中。 因此線程1必須等待線程0完成,依此類推。 我在#pragma omp關鍵部分中包含此部分。 一切運行正常,除了僅線程0完成,然后程序退出。 如何確保其他線程繼續輪詢? 我已經嘗試過sleep()和while循環,但是在線程0完成之后它繼續退出。
我沒有使用#pragma omp parallel,因為我需要跟蹤每個線程訪問的master數組的特定范圍。 這是相關代碼部分的簡化版本:
//DONE and MasterArray are global arrays. DONE keeps track of all the threads that have completed
int Function()
{
#pragma omp parallel
{
int ID = omp_get_thread_num
variables: start,end,i,j,temp(array) (all are initialized here)
j = 0;
for (i = start; i < end; i++)
{
if(i != start)
temp[j] = MasterArray[i];
else
temp[j] = temp[j-1] + MasterArray[i];
j++;
}
#pragma omp critical
{
while(DONE[ID] == 0 && ERROR == 0) {
int size = sizeof(temp) / sizeof(temp[0]);
if (ID == 0) {
Sum = temp[size];
DONE[ID] = 1;
if (some situation)
ERROR = 1; //there's an error and we need to exit the function and program
}
else if (DONE[ID-1] == 1) {
Sum = temp[size];
DONE[ID] = 1;
if (some situation)
ERROR = 1; //there's an error and we need to exit the function and program
}
}
}
}
if (ERROR == 1)
return(-1);
else
return(0);
}
初始化線程數后,從main調用此函數。 在我看來,並行部分完成了,然后我們檢查錯誤。 如果發現錯誤,則循環終止。 我意識到這里有問題,但是我無法弄清楚是什么,現在我只是轉圈而已。 任何幫助都會很棒。 再次,我的問題是該函數僅在線程0執行后退出,但未標記任何錯誤。 我也讓它在pthreads中運行,但是執行起來更簡單。 謝謝!
您嘗試使用#pragma omp critical
來訂購線程是完全錯誤的。 任何時候關鍵部分中只能有一個線程,並且線程到達關鍵部分的順序是不確定的。 因此,在您的代碼中可能會發生以下情況:例如,線程#2首先進入關鍵部分,再也不會離開它,等待線程#1完成,而線程#1和其余線程在#pragma omp critical
中等待。 而且,即使某些線程(例如線程#0)幸運地以正確的順序完成了關鍵部分,它們也會在並行區域末尾的隱式屏障上等待。 換句話說,此代碼幾乎可以確保死鎖。
我建議您對線程進行簡單而自然的排序,即有序部分。 它看起來應該像這樣:
#pragma omp parallel
{
int ID = omp_get_thread_num();
// Computations done by each thread
#pragma omp for ordered schedule(static,1)
for( int t=0; t<omp_get_num_threads(); ++t )
{
assert( t==ID );
#pragma omp ordered
{
// Do the stuff you want to be in order
}
}
}
因此,您將創建一個並行循環,其迭代次數等於該區域中的線程數。 使用schedule(static,1)
子句可以清楚地看到,每個線程按照線程ID的順序分配一次迭代; 和ordered
子句允許在循環內使用有序部分。 現在,在循環的主體中放置一個有序部分( #pragma omp ordered
的塊),它將以迭代的順序執行,這也是線程ID的順序(由斷言確保)。
有關更多信息,您可以查看以下問題: omp有序子句如何工作?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.