Visual C ++ Parallel_for + нарушение прав доступа к векторам - PullRequest
4 голосов
/ 04 августа 2011

Я пытаюсь преобразовать процесс, который проходит через матрицу ячеек ~ 12000x12000 (примерно 125 раз), чтобы использовать параллельную обработку (через parallel_for).Код, который я использую ниже.Вы можете видеть, где закомментирован цикл for.

Когда я запускаю этот код с циклом for, проблем не возникает.Когда я запускаю его (в режиме отладки), используя parallel_for, происходит сбой в случайных точках с «Необработанным исключением в 0x00f3d4ae в FratarProcess.exe 0xC0000005: Место записи нарушения доступа 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.

Ответы [ 3 ]

3 голосов
/ 07 августа 2011

Это также решит проблему:

Объявление объекта 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 в отличие от ручной синхронизации цикла.

3 голосов
/ 04 августа 2011

Вы не использовали защиту синхронизации для sqlStrings.Не безопасно изменять контейнер, выводить на печать или даже увеличивать общую переменную из нескольких потоков одновременно без использования синхронизации.

1 голос
/ 21 июня 2019

Вы также можете использовать класс Concurrent_Vector.

  1. Добавить #include<concurrent_vector.h>.
  2. , затем добавить using namespace concurrency;.
  3. Затем вы можете инициализировать вектор следующим образом: concurrent_vector<pair<int,int>> xy_coords;.

Использование этого вектора аналогично классу {std :: vector}.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...