Получение неверных результатов с OpenMP - PullRequest
2 голосов
/ 01 мая 2011

Я написал программу, которая умножает вектор на матрицу. В матрице периодически повторяются ячейки, поэтому я использую временную переменную для суммирования векторных элементов перед умножением. Период одинаков для соседних строк. Я создаю отдельную временную переменную для каждого потока. sizeof (InnerVector) == 400, и я не хочу выделять для него память при каждой итерации (= 600 раз).

Код выглядит примерно так:

tempsSize = omp_get_max_threads();
InnerVector temps = new InnerVector[tempsSize];

for(int k = 0; k < tempsSize; k++)
    InnerVector_init(temps[k]);

for(int jmin = 1, jmax = 2; jmax < matrixSize/2; jmin *= 2, jmax *= 2)
{
    int period = getPeriod(jmax);

    #pragma omp parallel
    {
        int threadNum = omp_get_thread_num();
        // printf("\n threadNum = %i", threadNum);

        #pragma omp for
        for(int j = jmin; j < jmax; j++)
        {
            InnerVector_reset(temps[threadNum]);   
            for(int i = jmin; i < jmax; i++)
            {
                InnerMatrix cell = getCell(i, j);
                if(temps[threadNum].IsZero)
                    for(int k = j; k < matrixSize; k += period)
                        InnerVector_add(temps[threadNum], temps[threadNum], v[k]);
                InnerVector_add_mul(v_res[i], cell, temps[threadNum]);
            }
        }
    }
}

Код выглядит правильно, но я получаю неправильный результат. На самом деле, я получаю разные результаты для разных прогонов ... иногда результат правильный.

Когда я компилирую в режиме отладки, результат всегда правильный. Когда я раскомментирую строку с помощью printf, результат всегда будет правильным.

p.s. Я использую Visual Studio 2010.

1 Ответ

3 голосов
/ 01 мая 2011

Я подозреваю, что в * 1001 может быть гонка данных InnerVector_add_mul(v_res[i], cell, temps[threadNum]);

Поскольку v_res представляется результирующим вектором, а i изменяется от jmin до jmax на каждой итерации параллельного цикла, может случиться так, что несколько потоков записывают в v_res[i] одно и то же значение i, с непредсказуемым результатом.

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