2011-08-03 93 views
4

我試圖轉換一個進程,通過~12,000x12,000單元矩陣(大約125次)循環使用並行處理(通過parallel_for)。我正在使用的代碼如下。你可以看到for循環被註釋掉的地方。Visual C++ parallel_for +向量訪問衝突

當我用for循環運行這段代碼時,沒有任何問題。當我使用parallel_for運行(調試),它崩潰在與「未處理的異常隨機點在FratarProcess.exe 0000005 0x00f3d4ae:訪問衝突寫入位置0x0000000

注:accessMatrix被聲明爲vector <vector <unsigned short> > accessMatrix;和之前充滿這點。

void dumpMatrix(unsigned short m) 
{ 

int complete=0, start=2532, todo=accessMatrix.size()-start; 

    vector <string> sqlStrings; 

    Concurrency::parallel_for(start, (int)accessMatrix.size(),[&complete,&todo,&m,&sqlStrings](int i) 
    //for(int i=start;i<accessMatrix.size();i++) 
    { 
     printf("Processing i=%i... completed %i/%i\n",i,complete,todo); 
     for(unsigned short j=1;j<accessMatrix[i].size();j++) 
     { 
      if(accessMatrix[i][j]>0) 
      { 
       stringstream strSQL; 
       strSQL << "INSERT INTO debug.dbf (I,J,M,V) VALUES(" << i << "," << j << "," << m << "," << accessMatrix[i][j] << ")"; 
       sqlStrings.push_back(strSQL.str()); 
      } 
     } 
     complete++; 
    }); 
... 
} 

有人可以幫我在正確的方向,所以我可以使用,而不是我的一個機器的所有8個內核得到這個過程嗎?請注意,我是位於C新手有點++的。我使用Visual C++ Express。

回答

2

你沒有使用過同步爲sqlStrings提供保護。對容器進行變異,打印輸出或甚至在不使用同步的情況下同時從多個線程增加共享變量是不安全的。

+0

好吧,所以在閱讀你的答案並做了一些更多的研究之後,看起來我應該將sqlStrings聲明爲'Concurrency :: concurrent_vector sqlStrings;',並且它可以運行一個測試。到現在爲止還挺好。感謝您讓我指出正確的方向。 –

3

這也將解決這個問題:

聲明一個combinable對象:

Concurrency::combinable<vector <string>> sqlStringsCombinable;

而且在循環:

sqlStringsCombinable.local().push_back(strSQL.str());

循環後,將它們結合起來:

sqlStringsCombinable.combine_each([&sqlStrings](const std::vector<CString>& vec) 
    { 
     std::copy(vec.cbegin(), vec.cend(), back_inserter(sqlStrings)); 
    }); 

而這會加速parallel_for而不是手動同步循環。

+0

我已經在上面標記了答案,但你的看起來也是正確的,我真的很感謝你發佈它。如果我有15個聲望要求我這樣做,我會投票贊成。再次感謝您發佈此信息。 –