Итерация через std-контейнеры в openmp

Я пытаюсь использовать 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

Параллелизация цикла для 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, который, скорее всего, будет частью С++ 17, может быть хороший вариант в будущем для итерации по стандартным контейнерам.