2009-06-01 2 views
41

Большинство людей в научных вычислениях используют OpenMP как квазистандарт, когда речь заходит о параллелизации разделяемой памяти.Параллелизация: pthreads или OpenMP?

Есть ли какая-либо причина (кроме удобочитаемости) использовать OpenMP поверх pthreads? Последнее кажется более базовым, и я подозреваю, что его можно было бы быстрее и проще оптимизировать.

ответ

37

Это в основном сводится к тому, какой уровень контроля вы хотите по сравнению с вашим распараллеливанием. OpenMP отлично, если все, что вы хотите сделать, это добавить несколько операторов #pragma и иметь параллельную версию вашего кода довольно быстро. Если вы хотите сделать действительно интересные вещи с MIMD-кодированием или сложной очередью, вы все равно можете сделать все это с помощью OpenMP, но, вероятно, гораздо проще использовать потоки в этом случае. OpenMP также имеет аналогичные преимущества в переносимости, поскольку многие компиляторы для разных платформ поддерживают его сейчас, как и pthreads.

Итак, вы абсолютно правы - если вам нужен точный контроль над вашим распараллеливанием, используйте pthreads. Если вы хотите распараллеливать работу с минимальными затратами, используйте OpenMP.

Каким бы способом вы ни решили, удачи!

20

Еще одна причина: OpenMP основан на задачах, Pthreads основан на потоках. Это означает, что OpenMP будет выделять столько же потоков, сколько количество ядер. Таким образом, вы получите масштабируемое решение. Это непростая задача сделать это с использованием необработанных потоков.

Второе мнение: OpenMP обеспечивает функции сокращения: когда вам нужно вычислить частичные результаты в потоках и объединить их. Вы можете реализовать его только с помощью одной строки кода. Но используя сырые потоки, вы должны делать больше работы.

Просто подумайте о своих требованиях и попытайтесь понять: достаточно ли OpenMP для вас? Вы сэкономите много времени.

+0

Пожалуйста разработать на масштабируемость решения. Масштабируемость применяется только во время компиляции или определяется во время выполнения? Или можно ли масштабировать время выполнения только потоками? – awiebe

+1

Вы можете установить количество потоков, созданных либо во время компиляции, либо во время выполнения. Если вы решите установить число, установленное во время выполнения, вы можете установить количество потоков через numthreads переменной окружения, чтобы его можно было легко установить на соответствующий номер в любой архитектуре, в которой вы его используете. –

+0

Этот ответ не имеет смысла. OpenMP - это потоковая модель, подобная потокам POSIX. У OpenMP даже не было задач для первых нескольких версий. – Jeff

6

OpenMP требует наличия компилятора, который поддерживает его, и работает с прагмами. Преимущество этого заключается в том, что при компиляции без поддержки OpenMP (например, PCC или Clang/LLVM на данный момент) код все равно будет компилироваться. Также обратите внимание на what Charles Leiserson wrote about DIY multithreading.

Pthreads - стандарт POSIX (IEEE POSIX 1003.1c) для библиотек, а OpenMP specifications - для компиляторов; что, как сказано, существует множество реализаций pthread (например, OpenBSD rthreads, NPTL) и ряд компиляторов, которые поддерживают OpenMP (например, GCC с флагом -fopenmp, MSVC++ 2008).

Pthreads эффективны только для распараллеливания при наличии нескольких процессоров и только тогда, когда код оптимизирован для количества доступных процессоров. Код для OpenMP более легко масштабируется в результате. Вы можете комбинировать код, который компилируется вместе с OpenMP с помощью кода с помощью pthreads.

+1

Последний параграф этого ответа - всевозможные ошибки. – Jeff

2

Вопрос вы похожи на вопрос «Должен ли я программировать C или сборку», C - OpenMP, а сборка - pthreads.

С помощью pthreads вы можете сделать гораздо более правильную параллелизацию, улучшенный смысл, очень сильно соответствующий вашему алгоритму и аппаратным средствам. Это будет очень много работы.

С помощью pthreads намного легче производить плохо параллелизированный код.

+0

Это предполагает, что OpenMP реализован с использованием Pthreads. Это не требуется, хотя в целом это правда. Если OpenMP был реализован для обнажения металла в специализированной архитектуре, он может быть быстрее, чем Pthreads. – Jeff

+0

@Jeff Я не предполагаю, что и мой ответ неинтересен деталям реализации. OpenMP и C более «высокоуровневые», чем сборка pthreads ans. Вот почему я считаю, что оба моих утверждения остаются верными, независимо от того, как реализованы C и OpenMP. – steffen

+0

Кажется, вы объединяете синтаксическую простоту OpenMP с семантическим бременем во время выполнения. Вы сравнили [спецификацию потока POSIX] (http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread.h.html) с [спецификацией OpenMP 4] (http://www.openmp.org/ Тпл-документы/OpenMP4.0.0.pdf)? В частности, рассмотрели ли вы, что требуется для 'pthread_create()' vs 'pragma omp parallel {}'? – Jeff

0

OpenMP идеален, когда вам необходимо выполнить ту же задачу параллельно (то есть, по нескольким данным), своего рода SIMD-машину (однонаправленные множественные данные).

Pthreads необходим, если вы хотите выполнять (совершенно разные) задачи параллельно, например, чтение данных в одном потоке и взаимодействие с пользователем в другом потоке.

Смотрите эту страницу:

http://berenger.eu/blog/c-cpp-openmp-vs-pthread-openmp-or-posix-thread/

+0

OpenMP всегда поддерживал больше, чем параллелизм данных. Вы действительно понимаете OpenMP? – Jeff

0

Есть ли какой-либо причине (кроме удобочитаемости) использовать OpenMP над Pthreads?

Майк вид коснулся этого:

OpenMP также имеет такие же преимущества в переносимости в том, что много компиляторов для различных платформ поддерживают его сейчас, как с Pthreads

Crypto++ является кросс-платформенный, что означает в прогонах Windows, Linux, OS X и BSD. Он использует OpenMP для поддержки потоковой передачи в тех местах, где операция может быть дорогостоящей, например, модульное возведение в степень и модульное умножение (и при этом возможна параллельная работа).

Windows не поддерживает pthreads, но современные компиляторы Windows поддерживают OpenMP. Поэтому, если вы хотите переносить на не-nix, то OpenMP часто является хорошим выбором.


И как Майк также отметил:

OpenMP является большим, если все, что вам нужно сделать, это добавить несколько заявлений #pragma и имеют параллельную версию кода довольно быстро.

Ниже приведен пример Crypto ++ предварительного вычисления некоторые значения, используемые в подписи Рабина-Williams, используя отлажены Корни, как описано Бернштейн в RSA signatures and Rabin-Williams signatures...:

void InvertibleRWFunction::Precompute(unsigned int /*unused*/) 
{ 
    ModularArithmetic modp(m_p), modq(m_q); 

    #pragma omp parallel sections 
    { 
     #pragma omp section 
      m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8); 
     #pragma omp section 
      m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8); 
     #pragma omp section 
      m_pre_q_p = modp.Exponentiate(m_q, m_p - 2); 
    } 
} 

Это согласуется с наблюдением Майка - точный контроль зерна и синхронизация была выполнена не нужно. Параллелизация была использована для ускорения выполнения, а синхронизация была бесплатной в исходном коде.

И если OpenMP является не доступен, код сводится к:

m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8); 
m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8); 
m_pre_q_p = modp.Exponentiate(m_q, m_p - 2); 
Смежные вопросы