std::valarray и распараллеливание
Может быть, это такой глупый вопрос.
На этом сайте я читал, что
Спецификация valarray позволяет библиотекам реализовать ее с несколькими оптимизациями эффективности, такими как распараллеливание определенных операций.
Что на данный момент с распараллеливанием std::valarray
на разных платформах и компиляторах? GCC, VS2010/2013, лязг?
Особенно со стандартной поддержкой потоков от C++11
,
UPD: И если некоторые компиляторы не поддерживают эту функцию. Каков наилучший способ сделать это: применить некоторые функции к элементам контейнера в нескольких потоках? Очевидно, наивное решение будет коротким и хорошо работает с std::thread
но может быть, существует лучшее решение?
1 ответ
Похоже, что Intel проделала определенную работу над этим.
Для других: я так не думаю. cppreference говорит, что
Некоторые реализации стандартной библиотеки C++ используют шаблоны выражений для реализации эффективных операций над std::valarray (например, GNU libstdC++ и LLVM libC++). Лишь в редких случаях оптимизируются valarrays, как, например, в Intel Parallel Studio.
Я также не нашел никакой документации о том, что libC++ или libstdC++ сделали что-то необычное в этом отношении, и обычно никто не скрывает интересных функций.:)
Учитывая MSVC: я однажды столкнулся с кодом, используя std::valarray
это скомпилировано, но не связано, потому что Microsoft "забыла" реализовать некоторые методы. Это, конечно, не является доказательством, но для меня это не звучит так, как будто ничего крутого там не произошло. Я также не мог найти документацию для специальных функций там.
Так что мы можем сделать вместо этого?
Например, мы можем использовать параллельный режим, чтобы libstdC++ распараллеливал следующие алгоритмы с OpenMP, где он считает это полезным:
std::accumulate
std::adjacent_difference
std::inner_product
std::partial_sum
std::adjacent_find
std::count
std::count_if
std::equal
std::find
std::find_if
std::find_first_of
std::for_each
std::generate
std::generate_n
std::lexicographical_compare
std::mismatch
std::search
std::search_n
std::transform
std::replace
std::replace_if
std::max_element
std::merge
std::min_element
std::nth_element
std::partial_sort
std::partition
std::random_shuffle
std::set_union
std::set_intersection
std::set_symmetric_difference
std::set_difference
std::sort
std::stable_sort
std::unique_copy
Для этого просто определите _GLIBCXX_PARALLEL
во время компиляции. Я чувствую, что это охватывает большую часть материала, который хотелось бы сделать с массивами чисел. Конечно
Обратите внимание, что определение _GLIBCXX_PARALLEL может изменить размеры и поведение стандартных шаблонов классов, таких как std::search, и поэтому можно связывать код, скомпилированный в параллельном режиме, и код, скомпилированный без параллельного режима, если между двумя экземплярами не передается экземпляр контейнера. переводческие единицы. Функциональность параллельного режима имеет четкую связь и не может быть перепутана с символами обычного режима.
( отсюда.)
Другим инструментом, который может помочь вам распараллелить, является советник Intel. Это более продвинутое и, я верю, также способное обрабатывать ваши циклы (никогда не использовал его сам), но, конечно, это проприетарное программное обеспечение.
Для операций линейной алгебры вы также можете найти хорошую параллельную LAPACK-реализацию.