Ложный общий доступ в OpenMP при записи в один вектор - PullRequest
0 голосов
/ 11 сентября 2018

Я изучил OpenMP, используя Тему Маттерсона, примечания к лекции , и он привел пример ложного обмена, как показано ниже.Код прост и используется для вычисления числа пи из числового интеграла 4,0 / (1 + x * x) с диапазоном х от 0 до 1. Код использует вектор для хранения значения 4,0 / (1 + х * х)для каждого x от 0 до 1, затем сложите вектор в конце:

#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main()
{
    int i, nthreads; double pi, sum[NUM_THREADS];
    step = 1.0/(double)num_steps;
    omp_set_num_threads(NUM_THREADS);
    #pragma omp parallel
    {
        int i, id, nthrds;
        double x;
        id = omp_get_thread_num();
        nthrds = omp_get_num_threads();
        if (id == 0) nthreads = nthrds;
        for (i=id, sum[id]=0.0; i<num_steps; i=i+nthrds){
            x = (i+0.5)*step;
            sum[id] += 4.0/(1.0+x*x);
        }
    }
    for (i=0; pi=0.0; i<nthreads;i++) pi += sum[i]*step;
}

У меня есть несколько вопросов о ложном разделении из этого примера:

  1. Является ли ложное разделение вызваннымтем, что задание на запись в массив периодически делится между двумя потоками, то есть [thread0, thread1, thread0, thread1, ...]?Если мы используем #pragma omp parallel for, то массив будет разделен на [thread0, thread0, thread0, ...., thread1, thread1, thread1, ...], тогда у нас все еще будет ложное совместное использование, теперь, когда адресдоступ из каждого потока находится далеко друг от друга?
  2. Если у меня есть задание, которое использует #pragma omp parallel for для записи в выходной вектор, который соответствует соотношению 1: 1 с моим входным вектором (например, входматрица предикторов и выходной вектор является предсказанием), тогда когда мне нужно беспокоиться о ложном обмене?

1 Ответ

0 голосов
/ 11 сентября 2018

Это руководство продолжает посылать сбитых с толку людей о переполнении стека - иногда не стоит учиться снизу вверх.

  1. Массив sum содержит только 2 === NUM_THREADS записей, т.е. [sum of thread 0, sum of thread 1].Эти значения, вероятно, находятся на одной и той же строке кэша, что вызывает ложное совместное использование.

  2. Если входной и выходной векторы достаточно (т.е. сотни элементов на потоки), все в порядке.Вы всегда должны использовать идиоматический OpenMP, то есть parallel for, а не ручную совместную работу, показанную в проблемных примерах этого руководства.Тогда у вас все в порядке по умолчанию, потому что OpenMP назначит смежные индексы одному и тому же потоку.

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

...