Распараллеливание: pthreads или OpenMP? - PullRequest
42 голосов
/ 01 июня 2009

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

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

Ответы [ 6 ]

39 голосов
/ 01 июня 2009

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

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

Какой бы путь вы ни решили, удачи!

22 голосов
/ 20 июня 2009

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

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

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

8 голосов
/ 29 декабря 2009

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

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

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

3 голосов
/ 22 июля 2012

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

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

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

1 голос
/ 14 июня 2015

Есть ли какая-либо причина (кроме читабельности) использовать 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);
0 голосов
/ 02 августа 2013

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

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

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

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

...