Вопрос

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

Ваш вопрос похож на вопрос "Должен ли я программировать C или assembly", где C - это OpenMP, а assembly - pthreads.

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

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

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

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

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

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

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


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

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

Ниже приведен пример предварительного вычисления Crypto ++ некоторых значений, используемых в сигнатурах Рабина-Уильямса, с использованием измененных корней, как описано Бернштейном в Подписи 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);

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top