4

~12,000x12,000 のセル マトリックス (約 125 回) をループするプロセスを変換して、並列処理を使用しようとしています (経由parallel_for)。私が使用しているコードは以下のとおりです。for ループがコメント アウトされている場所を確認できます。

このコードを for ループで実行すると、問題はありません。を使用して (デバッグで) 実行するとparallel_for、「FratarProcess.exe 0xC0000005 の 0x00f3d4ae で未処理の例外: アクセス違反の書き込み場所 0x0000000.

注:accessMatrixは as として宣言され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++;
    });
...
}

マシンの 1 つではなく 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 に答える