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-реализацию.

Другие вопросы по тегам