Visual Studio C++ 2015 и openMP

Я хочу знать поведение компилятора VC++ с /openmp. Я использую стороннюю библиотеку (OpenMVG), которая поставляется с cmakefilelist. Поэтому я сгенерировал решение Visual Studio для его компиляции. CMake распознает возможности openmp компилятора, и в VS все компилируется нормально. Но когда дело доходит до выполнения, я получаю разные результаты каждый раз, когда запускаю программу. А если я запускаю 2 экземпляра программы одновременно, то результаты еще хуже. Поэтому я немного заглянул в исходный код и обнаружил, что openmp используется с итераторами списка и карты.

#pragma omp parallel
for (Views::const_iterator iter = sfm_data.GetViews().begin(); iter != sfm_data.GetViews().end() && bContinue; ++iter)
{
  pragma omp single nowait
  { 
    ... process ... 
  }
}

Я искал в Интернете, и кажется, что Visual Studio поддерживает только openMP 2.0. Так поддерживает ли он итераторы списков? Может ли это быть проблемой? Как openMP 2.0 ведет себя с итераторами списка?

Заранее спасибо за любой ответ


person RobertoBa    schedule 19.12.2016    source источник
comment
Основная концепция этого кода заключается в выполнении всего цикла во всех потоках, а внутренний код цикла — только в отдельных потоках. Это в основном работает, но правильно ли это или работает хорошо, зависит от многих вещей, которые вы не показываете. Чтобы получить полезный ответ, вы должны предоставить минимальный воспроизводимый пример.   -  person Zulan    schedule 19.12.2016
comment
Что именно вы ожидали, что произойдет в любом случае? Основная предпосылка параллельного программирования состоит в том, что ваши структуры данных должны быть подходящими для того, чтобы распараллеливание работало. Конечно, вы можете обрабатывать элементы списка параллельно, но обход списка по своей сути является однопоточным. Требуется O(N) последовательных шагов, чтобы найти N-й элемент, без ярлыков.   -  person MSalters    schedule 19.12.2016
comment
Поскольку я получаю странные результаты, я просто спросил, может ли быть проблемой тот факт, что Visual Studio реализует версию 2.0 openMP, поскольку библиотека использует итераторы списка (не поддерживается 2.0). Я пытался скомпилировать библиотеку без поддержки openmp, и результаты выглядят стабильными при каждом выполнении.   -  person RobertoBa    schedule 19.12.2016
comment
полный код является повторной реализацией параллельного обхода коллекции без итератора произвольного доступа без задач. Все, кроме незначительного состояния гонки, которое срабатывает только в случае возникновения ошибки при загрузке одного из представлений, похоже, совместимо с OpenMP 2.0. Либо ошибка возникает где-то еще в коде, либо в среде выполнения MS OpenMP возникают проблемы с реализацией перекрывающихся областей single. Рассматривали ли вы возможность подать заявку на GitHub?   -  person Hristo Iliev    schedule 19.12.2016


Ответы (1)


Код не делает того, что вы, вероятно, думаете. Он создает набор потоков, каждый из которых выполняет один и тот же цикл.

Обратите внимание, что OpenMP в Visual Studio на самом деле не поддерживает C++, он рассматривает его как диалект C. В частности, /openmp не поддерживает итераторы, так как это только C++. Он поддерживает только (некоторые) циклы C.

Также обратите внимание, что OpenMP — это старый стандарт, предшествующий даже C++98. Начиная с C++11, C++ имеет встроенные возможности многопоточности.

person MSalters    schedule 19.12.2016
comment
OpenMP по-прежнему регулярно обновляется, например. с поддержкой атомарности, добавленной в 2013 году, и в этом смысле не старой. Только VS отказался поддерживать любую версию выше OpenMP 2.0. Ваша последняя строка также предполагает, что потоки OpenMP и С++ сопоставимы, но есть большая разница в том, что OpenMP может автоматически настроить пул потоков, а не создавать его самостоятельно. - person André; 19.12.2016
comment
OpenMP поддерживает итераторы произвольного доступа C++ с версии 3.0 (2008!). Самая последняя версия OpenMP выпущена в ноябре 2015 года, есть новый проект от ноября 2016 года. Единственная проблема заключается в том, что Visual Studio реализует версию 16-летней давности. - person Zulan; 19.12.2016
comment
@Zulan: Справедливое замечание, стало яснее, что я говорил об OpenMP, реализованном в Visual Studio. Что касается старого стандарта, вы также можете назвать его ранним стандартом, если вам так больше нравится. Он долгое время предоставлял возможности, которых не было в C++ до 2011 года. - person MSalters; 19.12.2016
comment
Я не понимаю ваш последний абзац. В C++11 есть встроенные потоки, но он не предоставляет ни одной из функций совместной работы OpenMP. - person Hristo Iliev; 19.12.2016
comment
@HristoIliev: Не могли бы вы использовать это для проблемы в вопросе? - person MSalters; 19.12.2016
comment
Проблема в вопросе неполная. Показанный код не имеет большого смысла, если только в конструкции single нет явных конструкций задач OpenMP, что является довольно распространенной идиомой. - person Hristo Iliev; 19.12.2016
comment
Я нашел полный код, на который ссылается OP, и, следовательно, отозвал свое предыдущее утверждение. По сути, это повторная реализация динамически запланированной конструкции for для класса-контейнера без типа итератора с произвольным доступом, использующая только конструкции из OpenMP 2.0. Его можно было реализовать с помощью явных задач, но они появились в более поздних версиях стандарта. - person Hristo Iliev; 19.12.2016