4

我正在尝试将循环通过 ~12,000x12,000 单元矩阵(大约 125 次)的过程转换为使用并行处理(通过parallel_for)。我正在使用的代码如下。您可以看到 for 循环被注释掉的位置。

当我使用 for 循环运行此代码时,没有问题。当我使用 运行它(在调试中)parallel_for时,它在随机点崩溃,并出现“FratarProcess.exe 0xC0000005 中 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。

4

3 回答 3

3

您没有对 sqlStrings 使用同步保护。在不使用同步的情况下,改变容器、打印到输出,甚至从多个线程同时增加共享变量是不安全的。

于 2011-08-04T16:54:07.537 回答
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与手动同步循环相比,这将加快速度。

于 2011-08-07T12:22:41.667 回答
1

您还可以使用 Concurrent_Vector 类。

  1. 添加#include<concurrent_vector.h>.
  2. 然后添加using namespace concurrency;.
  3. 然后你可以像这样初始化向量concurrent_vector<pair<int,int>> xy_coords;

这个向量的用法就像 {std::vector} 类。

于 2019-06-21T17:38:52.750 回答