Visual C ++ Access Violation parallel_for +

I am trying to convert a process that goes through a matrix of cells ~ 12 000x12000 (about 125 times) to use parallel processing (via parallel_for ). The code I'm using is below. You can see where the for loop is commented out.

When I run this code with a for loop, there is no problem. When I run it (debugging) using parallel_for , it crashes at random points using the "Unhandled exception at 0x00f3d4ae in the file FratarProcess.exe 0xC0000005: location of access violation record 0x0000000.

Note: accessMatrix declared as vector <vector <unsigned short> > accessMatrix; and is filled to this point.

 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++; }); ... } 

Can someone make me point in the right direction so that I can get this process using all 8 cores of my machine, not just one? Note that I'm a little new to C ++. I am using Visual C ++ Express.

+4
source share
3 answers

You did not use synchronization protection for sqlStrings. It is unsafe to mutate a container, print for output, or even increase a shared variable from multiple threads simultaneously without using synchronization.

+2
source

This will also solve the problem:

Declare a combinable object:

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

And in the loop:

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

After the loop, combine them:

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

And this will speed up parallel_for , unlike manual loop synchronization.

+3
source

You can also use the Concurrent_Vector class.

  1. Add #include<concurrent_vector.h> .
  2. then add using namespace concurrency; ,
  3. Then you can initialize the vector as follows: concurrent_vector<pair<int,int>> xy_coords; ,

Using this vector is similar to the class {std :: vector}.

0
source