У меня есть цикл, который я пытаюсь распараллелить, и в нем я заполняю контейнер, скажем, карту STL.Затем рассмотрим простой псевдокод ниже, где T1 и T2 - некоторые произвольные типы, тогда как f и g - некоторые функции целочисленного аргумента, возвращающие типы T1, T2 соответственно:
#pragma omp parallel for schedule(static) private(i) shared(c)
for(i = 0; i < N; ++i) {
c.insert(std::make_pair<T1,T2>(f(i),g(i))
}
Это выглядит довольно просто и выглядит какон должен быть тривиально распараллелен, но он не ускоряется, как я ожидал.Напротив, это приводит к ошибкам во время выполнения в моем коде из-за непредвиденных значений, заполняемых в контейнере, вероятно из-за условий гонки.Я даже пытался поставить барьеры и что-нет, но все безрезультатно.Единственное, что позволяет ему работать, это использовать директиву критической , как показано ниже:
#pragma omp parallel for schedule(static) private(i) shared(c)
for(i = 0; i < N; ++i) {
#pragma omp critical
{
c.insert(std::make_pair<T1,T2>(f(i),g(i))
}
}
Но этот вид делает бесполезным весь смысл использования omp в приведенном выше примере, так кактолько один поток одновременно выполняет большую часть цикла (оператор вставки контейнера).Что мне здесь не хватает?Если не считать изменения в написании кода, может кто-нибудь объяснить?