2011-08-03 73 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个声望要求我这样做,我会投票赞成。再次感谢您发布此信息。 –