поведение прагмы omp параллельно с циклами for - PullRequest
0 голосов
/ 03 января 2019

Кажется, я не совсем понимаю поведение параллельных конструкций openmp с вложенными циклами for.Рассмотрим следующий код:

std::size_t idx;
std::size_t idx2;
omp_set_num_threads( 2 );

#pragma omp parallel default(shared) private(idx, idx2)
{

  for(std::size_t idx=0;idx<3;idx++)
  {
    for(std::size_t idx2=0;idx2<4;idx2++)
    {
      LOG("From thread "+std::to_string(omp_get_thread_num())+" idx "+std::to_string(idx)+" idx2 "+std::to_string(idx2));
    }
  }
}

Это приводит к следующему выводу:

From thread 0 idx 0 idx2 0
From thread 1 idx 0 idx2 0
From thread 0 idx 0 idx2 1
From thread 1 idx 0 idx2 1
From thread 0 idx 0 idx2 2
From thread 1 idx 0 idx2 2
From thread 0 idx 0 idx2 3
From thread 1 idx 0 idx2 3
From thread 0 idx 1 idx2 0
From thread 1 idx 1 idx2 0
From thread 0 idx 1 idx2 1
From thread 1 idx 1 idx2 1
From thread 0 idx 1 idx2 2
From thread 1 idx 1 idx2 2
From thread 0 idx 1 idx2 3
From thread 1 idx 1 idx2 3
From thread 0 idx 2 idx2 0
From thread 1 idx 2 idx2 0
From thread 0 idx 2 idx2 1
From thread 1 idx 2 idx2 1
From thread 0 idx 2 idx2 2
From thread 1 idx 2 idx2 2
From thread 0 idx 2 idx2 3
From thread 1 idx 2 idx2 3

То, что происходит выше, состоит в том, что 2 потока назначены для выполнения двух вложенных циклов, и в результатеони производят вышеуказанный вывод (2 * 3 * 4 = всего 24 сообщения журнала), что просто.

Но теперь рассмотрим следующий код, в котором внутренний цикл for объявлен как pragma omp for

std::size_t idx;
std::size_t idx2;    
omp_set_num_threads( 2 );

#pragma omp parallel default(shared) private(idx, idx2)
{

  for(std::size_t idx=0;idx<3;idx++)
  {
    #pragma omp for
    for(std::size_t idx2=0;idx2<4;idx2++)
    {
      LOG("From thread "+std::to_string(omp_get_thread_num())+" idx "+std::to_string(idx)+" idx2 "+std::to_string(idx2));
    }
  }
}

Это приводит к следующим 3 * 4 = 12 сообщениям в журнале:

From thread 0 idx 0 idx2 0
From thread 1 idx 0 idx2 2
From thread 0 idx 0 idx2 1
From thread 1 idx 0 idx2 3
From thread 0 idx 1 idx2 0
From thread 1 idx 1 idx2 2
From thread 0 idx 1 idx2 1
From thread 1 idx 1 idx2 3
From thread 0 idx 2 idx2 0
From thread 0 idx 2 idx2 1
From thread 1 idx 2 idx2 2
From thread 1 idx 2 idx2 3

Я бы ожидал, что еще два потока будут назначены коду, соответствующему двум внутренним циклам for, и получим снова 24выходные сообщения.Почему выходные данные отличаются в этих двух случаях?

1 Ответ

0 голосов
/ 03 января 2019

В первом случае #pragma omp parallel запускает всю параллельную область один раз в каждом потоке. Это означает, что оба потока будут работать для обоих циклов полностью, поэтому каждый поток должен генерировать 4 * 3 = 12 строк вывода.

Во втором случае внутренний #pragma omp for сообщает компьютеру, что внутренний цикл for в idx2 должен быть разделен между доступными потоками. Таким образом, вместо того, чтобы оба потока выполняли внутренний цикл от 0 до idx2, каждая итерация внутреннего цикла будет выполняться ровно один раз.

Во втором выводе мы должны увидеть, что все значения idx2 печатаются ровно один раз для каждого значения idx и из любого потока, который был доступен.

например. если idx может быть только нулем, вывод может выглядеть примерно так:

From thread ? idx 0 idx2 0
From thread ? idx 0 idx2 1
From thread ? idx 0 idx2 2
From thread ? idx 0 idx2 3

где ? означает, что это может быть любой доступный поток.

...