Подтвердить что ты не робот

Параллелизация: pthreads или OpenMP?

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

OpenMP требует компилятора, который его поддерживает, и работает с прагмами. Преимущество этого заключается в том, что при компиляции без поддержки OpenMP (например, PCC или Clang/LLVM на данный момент) код все равно будет компилироваться. Кроме того, посмотрите что написал Чарльз Лейзерсон о многопоточности DIY.

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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

Ответ 6

Есть ли какая-либо причина (кроме чтения) использовать OpenMP поверх pthreads?

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

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

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

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


И как сказал Майк:

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

Ниже приведен пример Crypto ++, предварительно вычисляющий некоторые значения, используемые в сигнатурах Рабина-Уильямса с использованием Tweaked Roots, как описано Бернштейном в RSA-сигнатурах и подписи Рабина-Вильямса..

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);