2012-09-13 48 views
0

這是我迄今爲止所做的解決return 1;,return 0;,它實際上是一個使用回溯算法的數獨求解器,所以我試圖並行化它,但我無法得到完整的結果。 (糾正我,如果我的實施是錯誤的) 實際發生了什麼?有人可以幫忙嗎?!如何解決打開mp中的for循環中的「返回0或返回1」?

這是我指的是網站,我曾經按照自己的方式:http://www.thinkingparallel.com/2007/06/29/breaking-out-of-loops-in-openmp/#reply

int solver (int row, int col) 
{ 
    int i; 
    boolean flag = FALSE; 
    if (outBoard[row][col] == 0) 
    { 
     #pragma omp parallel num_threads(2) 
     #pragma omp parallel for //it works if i remove this line 
     for (i = 1; i < 10; i++) 
     { 
     if (checkExist(row, col, i)) //if not, assign number i to the empty cell 
      outBoard[row][col] = i; 

     #pragma omp flush (flag) 
     if (!flag) 
     { 
      if (row == 8 && col == 8) 
      { 
       //return 1; 
       flag = TRUE; 
       #pragma omp flush (flag) 
      } 
      else if (row == 8) 
      { 
       if (solver(0, col+1)) 
       { 
        //return 1; 
        flag = TRUE; 
        #pragma omp flush (flag) 
       } 
      } 
      else if (solver(row+1, col)) 
      { 
       //return 1; 
       flag = TRUE; 
       #pragma omp flush (flag) 
      } 
     } 
     } 


     if (flag) { return 1; } 

     if (i == 10) 
     { 
      if (outBoard[row][col] != inBoardA[row][col]) 
      outBoard[row][col] = 0; 
     return 0; 
      } 

    } 
    else 
     { 
     if (row == 8 && col == 8) 
     { 
     return 1; 
      } 
     else if (row == 8) 
     {  
      if (solver(0,col+1)) return 1; 
      } 
      else 
      { 
      if (solver(row+1,col)) return 1; 
      } 

    return 0; 
    } 
} 

5 0 0 0 0 3 7 0 0 
7 4 6 1 0 2 3 0 0 
0 3 8 0 9 7 5 0 2 
9 7 0 4 0 0 2 0 0 
0 0 2 0 0 0 4 0 0 
0 0 4 0 0 5 0 1 9 
4 0 3 2 7 0 9 8 0 
0 0 5 3 0 9 6 7 4 
0 0 7 5 0 0 0 0 3 
Sudoku solved : 
5 2 9 8 0 3 7 4 1 
7 4 6 1 5 2 3 9 0 
1 3 8 0 9 7 5 6 2 
9 7 0 4 1 0 2 3 6 
0 1 2 9 6 0 4 5 8 
3 6 4 7 8 5 0 1 9 
4 0 3 2 7 6 9 8 5 
2 8 5 3 0 9 6 7 4 
6 9 7 5 4 8 1 2 3 

//return 1;是原始串行代碼,因爲returnparallel for是不允許的,所以我用#pragma opm flush來消除它,但結果並不完整,它仍然在數獨中留下了很少的空格。

謝謝回答:>

+0

「我希望我的代碼不會把你搞砸」不,不,但是你的拼寫和語法很糟糕。請至少嘗試清理它,所以它是可讀的。 –

+0

@Tony,原諒我可憐的英語,我會改進它。如果你能回答我的問題,我很高興? – CT5275

+0

我對openmp沒有任何經驗,所以幫不了你。對不起:( –

回答

0

首先,由於solver被遞歸調用,它雙打遞歸的每級的線程數。我不認爲這是你打算做的。 編輯:只有在啓用嵌套並行時使用omp_set_nested(),並且默認情況下它不是。所以只有solver的第一個電話將被分叉。

#pragma omp parallel num_threads(2) 
#pragma omp parallel for 

在你的代碼試圖在另一個創建一個並行區域,而且會導致隨後執行兩次循環,因爲外parallel已經創建了兩個線程。應將其替換爲

#pragma omp parallel num_threads(2) 
#pragma omp for 

或等效的#pragma omp parallel for num_threads(2)

其次,這種代碼:

if (checkExist(row,col,i))//if not, assign number i to the empty cell 
    outBoard[row][col] = i; 

創建的競爭條件,與兩個線程並行寫入不同的值相同的小區。您可能需要爲每個線程創建單獨的電路板副本。

另一代碼的一部分,

if (outBoard[row][col] != inBoardA[row][col]) 
    outBoard[row][col] = 0; 

似乎是並行區域外,但在嵌套調用solver它在由最外solver創建不同的線程並行也執行。

決賽(E)(18.09)無論如何,即使你設法調試/更改代碼並行運行正常(因爲我自己做只是爲了赫克 - 我會盡力提供代碼如果任何人有興趣,我懷疑),結果將是這個代碼的並行執行不會給你太多的優勢。我想到的原因如下:

想象一下,當solver迭代9個可能的單元值時,它會創建9個執行分支。如果使用OpenMP創建2個線程,它將以某種方式在線程之間分配頂級分支,比如5個分支由一個線程執行,另一個執行4個分支,並且在每個線程中分支將逐個連續執行。如果初始數獨狀態有效,則只有一個分支會導致正確的解決方案。其他分支機構在解決方案出現差異時會被縮短,因此有些分支機構需要更長的時間,而有些分支機構的運行時間會更短,而導致正確解決方案的分支機構運行時間最長。您無法預測哪些分支需要什麼時間執行,因此無法合理平衡線程間的工作負載。即使使用OpenMP動態調度,也可能是一個線程執行最長的分支時,其他線程已經完成所有其他分支,並且將等待最後一個分支,因爲分支太少(所以動態調度將是幫助不大)。由於在它們之間創建線程和同步數據會產生一些相當大的開銷(與連續的solver運行時間爲0.01-10 ms相比),根據輸入的不同,並行執行時間會稍長於或短於順序。

在任何情況下,如果順序解算器運行時間低於10毫秒,爲什麼要使其平行?

+1

只有在顯式啓用嵌套並行機制時纔會發生遞歸線程加倍,因爲默認情況下它是禁用的。 –

+0

是的,函數沒有完成,if(flags)函數後面還有幾行 – CT5275

+0

我想,如果找不到解決方案,那麼你清除了單元格,從而產生更多的混淆。所以一個線程可能會清除該單元,而另一個線程仍然認爲它可以與其自己的版本一起工作。 –