2014-03-30 32 views
2

因此,我正在研究此項目,並且正在編寫Chapel計算語言。我已經編寫了該程序,並且在未並行化運行時可以很好地工作。在並行化過程中在Chapel中使用同步變量時遇到問題

但是當我添加我需要並行化的語句時,程序確實運行得更快,但它不能提供我需要的結果。我知道的是因爲我在步驟1,3,5和7中遇到競爭條件,當我做j = j - 1;時,我嘗試使j爲同步變量,以防止這種競爭條件破壞我的結果,然後編譯,運行和我的程序永遠不會使其脫離步驟1,這是第一個同步變量的位置,所以我有理由相信這是因爲同步變量j

如果任何人有任何關於我應該如何並行化或同步的洞察力,以便我的最終網格排序,那將是非常好的。以下是代碼:

//SlideSort.chapel_version 
// 

use Random; 
use Time; 

config const seed = 2345; 
var rs = new RandomStream(seed); 
var num: int; 
var transferMesh:[0..36530] int; 
var copyMesh:[0..36530] int; 
var mesh:[0..37883] int; 
var i: int; 
var z: int; 



    proc slideSort(){ 
     writeln("\nSorting..\n"); 
/*-------------------------Step 1-------------------------------*/ 
     writeln("Step 1"); 
     forall i in 0..36530{ 
     transferMesh[i] = mesh[i+677]; 
     }//end for 

     forall i in 0..1352{ 
     forall a in 0..26{ 
      var value: int = transferMesh[1353*a+i]; 
      var j$: int = 1353*a+i-1; 
       while j$>= 1353*a && transferMesh[j$] > value{ 
        transferMesh[j$+1] = transferMesh[j$]; 
        j$ = j$ - 1; 
       }//end While 
       transferMesh[j$+1] = value; 
     }//end a_for 
     }//end i_for 

     forall k in 0..36530{ 
     mesh[k+677] = transferMesh[k]; 
     }//end For_k 
/*--------------------------Step 2--------------------------------*/ 
     writeln("Step 2"); 
     forall k in 677..37207{ 
      transferMesh[k-677] = mesh[k]; 
     }//end k_for 

     forall k in 0..1352{ 
      for z in 0..26{ 
       copyMesh[k+1353*z] = transferMesh[27*k+z]; 
      }//end z_for 
     }//end k_for 

     forall k in 0..36530{ 
      mesh[k+677] = copyMesh[k]; 
     }//end k_for 
/*--------------------------Step 3--------------------------------*/ 
     writeln("Step 3"); 
     forall i in 0..36530{ 
      transferMesh[i] = mesh[i+677]; 
     }//end for 

     forall i in 0..1352{ 
      forall a in 0..26{ 
       var value: int = transferMesh[1353*a+i]; 
       var j: int = 1353*a+i-1; 
        while j>= 1353*a && transferMesh[j] > value{ 
        transferMesh[j+1] = transferMesh[j]; 
        j = j - 1; 
        }//end While 
        transferMesh[j+1] = value; 
      }//end a_for 
     }//end i_for 

     forall k in 0..36530{ 
      mesh[k+677] = transferMesh[k]; 
     }//end For_k 
/*--------------------------Step 4--------------------------------*/ 
     writeln("Step 4"); 
     forall k in 677..37207{ 
      transferMesh[k-677] = mesh[k]; 
     }//end for 

     forall k in 0..1352{ 
      forall z in 0..26{ 
       copyMesh[27*k+z] = transferMesh[k+1353*z]; 
      }//end z_for 
     }//end k_for 

     forall k in 0..36530{ 
      mesh[k+677] = copyMesh[k]; 
     }//end k_for 
/*--------------------------Step 5--------------------------------*/ 
     writeln("Step 5"); 
     forall i in 0..36530{ 
      transferMesh[i] = mesh[i+677]; 
     }//end for 

     forall i in 0..1352{ 
      forall a in 0..26{ 
       var value: int = transferMesh[1353*a+i]; 
       var j: int = 1353*a+i-1; 
        while j>= 1353*a && transferMesh[j] > value{ 
        transferMesh[j+1] = transferMesh[j]; 
        j = j - 1; 
        }//end While 
        transferMesh[j+1] = value; 
      }//end a_for 
     }//end i_for 

     forall k in 0..36530{ 
      mesh[k+677] = transferMesh[k]; 
     }//end For_k 
/*--------------------------Step 6--------------------------------*/ 
     writeln("Step 6"); 
     /*This is the padding step, so, since I already have a padded array 
      I will simply just sort my padded array in step 7 
     */ 
/*--------------------------Step 7--------------------------------*/ 
     writeln("Step 7\n"); 
     forall k in 0..1352{ 
      forall a in 0..27{ 
       var value: int = mesh[1353*a+k]; 
       var j: int = 1353*a+k-1; 
       while j >= 1353 *a && mesh[j] > value{ 
        mesh[j+1] = mesh [j]; 
        j = j - 1; 
       }//end while 
       mesh[j+1] = value; 
      }//end a_for 
     }//end k_for 


    }//slideSort END 
/*^^^^^^^^^^^^^^^^^^^^^^^end slidesort^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 

    proc isSorted() :int{ 
     var sorted: int = 0; 
     for i in 0..37882{ 
     if mesh[i+1] < mesh[i]{ 
      writeln("NOT SORTED :("); 
      sorted = 1; 
      break; 
     }//if 
     }//end For 
     return sorted; 
    }// isSorted END 



proc main(){ 

/*Padding array with -INF*/ 
    for i in 0..676 do mesh[i] = -1000000; 

/*Filling array with random ints*/ 
    for i in 677..37207{ 
     num = (301 * rs.getNext()): int; 
     mesh[i] = num; 
    }//end for 

/*Padding array with +INF*/ 
    for i in 37208..37883 do mesh[i] = 1000000; 


    writeln("\n200th Element: ", mesh[199],"\n1000th Element: ", mesh[999]); 
    writeln("30000th Element: ", mesh[29999], "\n37300th Element: ", mesh[37299]); 

    const startTime = getCurrentTime(); 
    slideSort(); 
    const endTime = getCurrentTime(); 

    writeln("\n200th Element: ", mesh[199], "\n1000th Element: ", mesh[999]); 
    writeln("30000th Element: ", mesh[29999], "\n37300th Element: ", mesh[37299]); 

    writeln("\n\nElapsed time was: ", (endTime - startTime)); 

    if(isSorted()==0) then writeln("\nYep the mesh is sorted via SlideSort :)"); 

    write("\nWould you like to print out every 100th element of the Mesh?\n", 
      "'Y' for yes\n", 
      "'N' for no\n"); 
    var print: string = "N"; 
    print = stdin.read(string); 

    if print == "Y" || print == "y"{ 
     for i in 0..37883 by 100{ 
     write(mesh[i],"\n"); 
     }//end innerFor 
    }//end if 

}//end MAIN 
+0

是的,我知道j是沒有在我發佈的代碼中同步,我試圖在發佈之前找到另一個解決方案,並且忘記將其重新放入。任何幫助! –

回答

1

它與同步變量沒有太大關係。你的雙環看起來像這樣:

forall i in 0..1352 do 
    forall a in 0..26 
    { 
     var j = 1353*a+i; 
     var v = transferMesh[j]; 

     while(j>= 1353*a) 
     { 
      if(transferMesh[j] <= v) 
       break; 

      transferMesh[j+1] = transferMesh[j]; 
      j--; 
     } 

     transferMesh[j+1] = v; 
    } 

這是一個明顯的數據競賽來源。您測試transferMesh[j],但由於具有相同a的另一個i可以同時迭代,它可能會同時修改該值,導致未定義的結果。

對於這些循環中的每一個,每個塊只允許一個工人(因此每個值爲a)。因此,你應該同時只有通過迭代,即forall a in 0..26 do for i in 0..1352 {...}


因此容易得到糾正代碼:

//SlideSort.chapel_version 
// 

use Random; 
use Time; 

config const seed = 2345; 
var rs = new RandomStream(seed); 
var num: int; 
var transferMesh:[0..36530] int; 
var copyMesh:[0..36530] int; 
var mesh:[0..37883] int; 
var i: int; 
var z: int; 



proc slideSort() 
{ 
    writeln("\nSorting..\n"); 
    /*-------------------------Step 1-------------------------------*/ 
    writeln("Step 1"); 
    forall i in 0..36530 
    { 
    transferMesh[i] = mesh[i+677]; 
    }//end for 

    forall a in 0..26 
    { 
    for i in 0..1352 
    { 
     var value: int = transferMesh[1353*a+i]; 
     var j: int = 1353*a+i-1; 
     while j>= 1353*a && transferMesh[j] > value 
     { 
     transferMesh[j+1] = transferMesh[j]; 
     j = j - 1; 
     }//end While 
     transferMesh[j+1] = value; 
    }//end i_for 
    }//end a_for 

    forall k in 0..36530 
    { 
    mesh[k+677] = transferMesh[k]; 
    }//end For_k 
    /*--------------------------Step 2--------------------------------*/ 
    writeln("Step 2"); 
    forall k in 677..37207 
    { 
    transferMesh[k-677] = mesh[k]; 
    }//end k_for 

    forall z in 0..26 
    { 
    forall k in 0..1352 
    { 
     copyMesh[k+1353*z] = transferMesh[27*k+z]; 
    }//end k_for 
    }//end z_for 

    forall k in 0..36530 
    { 
    mesh[k+677] = copyMesh[k]; 
    }//end k_for 
    /*--------------------------Step 3--------------------------------*/ 
    writeln("Step 3"); 
    forall i in 0..36530 
    { 
    transferMesh[i] = mesh[i+677]; 
    }//end for 

    forall a in 0..26 
    { 
    for i in 0..1352 
    { 
     var value: int = transferMesh[1353*a+i]; 
     var j: int = 1353*a+i-1; 
     while j>= 1353*a && transferMesh[j] > value 
     { 
     transferMesh[j+1] = transferMesh[j]; 
     j = j - 1; 
     }//end While 
     transferMesh[j+1] = value; 
    }//end i_for 
    }//end a_for 

    forall k in 0..36530 
    { 
    mesh[k+677] = transferMesh[k]; 
    }//end For_k 
    /*--------------------------Step 4--------------------------------*/ 
    writeln("Step 4"); 
    forall k in 677..37207 
    { 
    transferMesh[k-677] = mesh[k]; 
    }//end for 

    forall k in 0..1352 
    { 
    for z in 0..26 
    { 
     copyMesh[27*k+z] = transferMesh[k+1353*z]; 
    }//end z_for 
    }//end k_for 

    forall k in 0..36530 
    { 
    mesh[k+677] = copyMesh[k]; 
    }//end k_for 
    /*--------------------------Step 5--------------------------------*/ 
    writeln("Step 5"); 
    forall i in 0..36530 
    { 
    transferMesh[i] = mesh[i+677]; 
    }//end for 

    forall a in 0..26 
    { 
    for i in 0..1352 
    { 
     var value: int = transferMesh[1353*a+i]; 
     var j: int = 1353*a+i-1; 
     while j>= 1353*a && transferMesh[j] > value 
     { 
     transferMesh[j+1] = transferMesh[j]; 
     j = j - 1; 
     }//end While 
     transferMesh[j+1] = value; 
    }//end i_for 
    }//end a_for 

    forall k in 0..36530 
    { 
    mesh[k+677] = transferMesh[k]; 
    }//end For_k 
    /*--------------------------Step 6--------------------------------*/ 
    writeln("Step 6"); 
    /*This is the padding step, so, since I already have a padded array 
    I will simply just sort my padded array in step 7 
    */ 
    /*--------------------------Step 7--------------------------------*/ 
    writeln("Step 7\n"); 
    forall a in 0..27 
    { 
    for k in 0..1352 
    { 
     var value: int = mesh[1353*a+k]; 
     var j: int = 1353*a+k-1; 
     while j >= 1353 *a && mesh[j] > value 
     { 
     mesh[j+1] = mesh [j]; 
     j = j - 1; 
     }//end while 
     mesh[j+1] = value; 
    }//end k_for 
    }//end a_for 


}//slideSort END 
/*^^^^^^^^^^^^^^^^^^^^^^^end slidesort^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 

proc isSorted() :int 
{ 
    var sorted: int = 0; 
    for i in 0..37882 
    { 
    if mesh[i+1] < mesh[i] 
    { 
     writeln("NOT SORTED :("); 
     sorted = 1; 
     break; 
    }//if 
    }//end For 
    return sorted; 
}// isSorted END 



proc main() 
{ 

    /*Padding array with -INF*/ 
    for i in 0..676 do mesh[i] = -1000000; 

    /*Filling array with random ints*/ 
    for i in 677..37207 
    { 
    num = (301 * rs.getNext()): int; 
    mesh[i] = num; 
    }//end for 

    /*Padding array with +INF*/ 
    for i in 37208..37883 do mesh[i] = 1000000; 


    writeln("\n200th Element: ", mesh[199],"\n1000th Element: ", mesh[999]); 
    writeln("30000th Element: ", mesh[29999], "\n37300th Element: ", mesh[37299]); 

    const startTime = getCurrentTime(); 
    slideSort(); 
    const endTime = getCurrentTime(); 

    writeln("\n200th Element: ", mesh[199], "\n1000th Element: ", mesh[999]); 
    writeln("30000th Element: ", mesh[29999], "\n37300th Element: ", mesh[37299]); 

    writeln("\n\nElapsed time was: ", (endTime - startTime)); 

    if(isSorted()==0) then writeln("\nYep the mesh is sorted via SlideSort :)"); 

}//end MAIN 

結果:

$ chpl sort.chpl ; ./a.out | tail -n 1 
Yep the mesh is sorted via SlideSort :) 
相關問題