Итерация через стандартные контейнеры в openmp - PullRequest
19 голосов
/ 25 марта 2010

Я пытаюсь использовать openmp для многопоточности цикла через std :: set. Когда я пишу следующий код -

    #pragma omp parallel for
    for (std::set<A>::const_iterator i = s.begin(); i != s.end(); ++i) {
            const A a = *i;
            operate(a);
    }

Я получаю эту ошибку:

error: invalid type for iteration variable 'i'
error: invalid controlling predicate
error: invalid increment expression.

Есть ли другой, правильный способ перебора контейнеров std с использованием openmp? Я знаю, что могу использовать int i и выполнять итерацию от 0 до s.size() и итератор или operator[] в теле цикла, но это выглядит гораздо менее чисто.

1 Ответ

23 голосов
/ 25 марта 2010

Распараллеливание цикла для итераторов stl работает только с OpenMP 3.0 и только для итераторов с произвольным доступом (например, vector и deque). Вы должны быть в состоянии сделать что-то вроде этого:

#pragma omp parallel {
   for (std::set<A>::const_iterator i = s.begin(); i != s.end(); ++i) {
      #pragma omp single nowait {
         operate(*i);
      }
   }
}

Затраты довольно велики, потому что каждый поток выполняет итерацию по всей последовательности (но только для некоторых из них operate). Ваш метод, использующий int i, более эффективен.

В качестве альтернативы взгляните на параллельную реализацию GCC std::for_each. Смотрите мой комментарий.

EDIT : STL Parallism TS , который, скорее всего, станет частью C ++ 17, в будущем может стать хорошим вариантом для перебора стандартных контейнеров.

...