OpenMP управляется некоммерческим технологическим консорциумом OpenMP Architecture Review Board (или OpenMP ARB ), совместно определяемым широким кругом ведущих поставщиков компьютерного оборудования и программного обеспечения, включая Arm , AMD , IBM , Intel , Cray , HP , Fujitsu , Nvidia , NEC , Red Hat , Texas Instruments и Oracle Corporation . [1]
Приложение, созданное с использованием гибридной модели параллельного программирования, может работать на кластере компьютеров, используя как OpenMP, так и Message Passing Interface (MPI), так что OpenMP используется для параллелизма в пределах (многоядерного) узла, а MPI используется для параллелизма между узлами. Также были попытки запустить OpenMP на программно-распределенных системах с общей памятью , [6] чтобы перевести OpenMP в MPI [7] [8]
и расширить OpenMP для систем с необщей памятью. [9]
Дизайн
OpenMP — это реализация многопоточности , метода распараллеливания, при котором основной поток (серия последовательно выполняемых инструкций) разветвляется на определенное количество подпотоков , и система делит задачу между ними. Затем потоки выполняются одновременно , при этом среда выполнения распределяет потоки по разным процессорам.
Раздел кода, который должен выполняться параллельно, помечается соответствующим образом директивой компилятора, которая заставит потоки сформироваться до выполнения раздела. [3] Каждый поток имеет прикрепленный к нему идентификатор , который можно получить с помощью функции (называемой omp_get_thread_num()). Идентификатор потока представляет собой целое число, а основной поток имеет идентификатор 0. После выполнения распараллеленного кода потоки снова объединяются в основной поток, который продолжается до конца программы.
По умолчанию каждый поток выполняет распараллеленный раздел кода независимо. Конструкции разделения работы могут использоваться для разделения задачи между потоками, чтобы каждый поток выполнял выделенную ему часть кода. Таким образом, с помощью OpenMP можно достичь как параллелизма задач , так и параллелизма данных .
Среда выполнения распределяет потоки по процессорам в зависимости от использования, загрузки машины и других факторов. Среда выполнения может назначать количество потоков на основе переменных среды , или код может делать это с помощью функций. Функции OpenMP включены в заголовочный файл с меткой omp.h в C / C++ .
История
Совет по рассмотрению архитектуры OpenMP (ARB) опубликовал свои первые спецификации API, OpenMP для Fortran 1.0, в октябре 1997 года. В октябре следующего года они выпустили стандарт C/C++. В 2000 году вышла версия 2.0 спецификаций Fortran, а версия 2.0 спецификаций C/C++ была выпущена в 2002 году. Версия 2.5 представляет собой объединенную спецификацию C/C++/Fortran, выпущенную в 2005 году. [ необходима цитата ]
До версии 2.0 OpenMP в первую очередь специализировал способы распараллеливания высокорегулярных циклов, как это происходит в матрично-ориентированном численном программировании , где число итераций цикла известно на момент входа. Это было признано ограничением, и к реализациям были добавлены различные расширения параллельной задачи. В 2005 году была сформирована попытка стандартизировать параллелизм задач, которая опубликовала предложение в 2007 году, черпая вдохновение из функций параллелизма задач в Cilk , X10 и Chapel . [10]
Версия 3.0 была выпущена в мае 2008 года. В число новых функций версии 3.0 вошли концепция задач и конструкция задачи , [11] значительно расширяющие область применения OpenMP за пределы конструкций параллельных циклов, которые составляли большую часть OpenMP 2.0. [12]
Текущая версия — 5.2, выпущенная в ноябре 2021 года. [15]
Версия 6.0 должна выйти в 2024 году. [16]
Обратите внимание, что не все компиляторы (и операционные системы) поддерживают полный набор функций последней версии/версий.
Основные элементы
Основными элементами OpenMP являются конструкции для создания потоков, распределения рабочей нагрузки (совместного использования работы), управления данными и средой, синхронизации потоков, процедуры выполнения на уровне пользователя и переменные среды.
В C/C++ OpenMP использует #pragmas . Конкретные прагмы OpenMP перечислены ниже.
Создание темы
Прагма omp parallel используется для разветвления дополнительных потоков для параллельного выполнения работы, заключенной в конструкции. Исходный поток будет обозначен как главный поток с идентификатором потока 0.
Пример (программа на языке C): Отображение «Hello, world.» с использованием нескольких потоков.
Используйте флаг -fopenmp для компиляции с использованием GCC:
$ gcc -fopenmp привет.c -o привет -ldl
Вывод на компьютере с двумя ядрами и, следовательно, двумя потоками:
Привет, мир.Привет, мир.
Однако вывод также может быть искажен из-за состояния гонки, вызванного тем, что два потока совместно используют стандартный вывод .
Привет, привет, привет.рлд.
Является ли printfон атомарным, зависит от базовой реализации [17], в отличие от C++11 std::cout, который по умолчанию является потокобезопасным. [18]
Конструкции разделения труда
Используется для указания способа назначения независимой работы одному или всем потокам.
omp for или omp do : используются для разделения итераций цикла между потоками, также называются конструкциями цикла.
разделы : назначение последовательных, но независимых блоков кода разным потокам
single : указание блока кода, который выполняется только одним потоком, в конце подразумевается барьер
master : аналогично single, но блок кода будет выполнен только главным потоком, и в конце не будет подразумеваться никакого барьера.
Пример: инициализация значения большого массива параллельно, используя каждый поток для выполнения части работы.
int main ( int argc , char ** argv ) { int a [ 100000 ];#pragma omp parallel for for ( int i = 0 ; i < 100000 ; i ++ ) { a [ i ] = 2 * i ; }вернуть 0 ; }
Этот пример ошеломляюще параллелен и зависит только от значения i . Флаг параллельности OpenMP for сообщает системе OpenMP о необходимости разделить эту задачу между ее рабочими потоками. Каждый поток получит уникальную и закрытую версию переменной. [19] Например, при наличии двух рабочих потоков одному потоку может быть передана версия i , которая работает от 0 до 49999, а второму — версия, работающая от 50000 до 99999.
Варианты директив
Директивы вариантов являются одной из основных функций, введенных в спецификации OpenMP 5.0 для облегчения программистам задачи повышения производительности и переносимости. Они позволяют адаптировать прагмы OpenMP и пользовательский код во время компиляции. Спецификация определяет черты для описания активных конструкций OpenMP, исполнительных устройств и функциональности, предоставляемой реализацией, селекторы контекста на основе черт и определяемых пользователем условий, а также директивы метадирективы и директивы объявления для программирования пользователями той же области кода с помощью директив вариантов.
Метадиректива — это исполняемая директива, которая условно преобразуется в другую директиву во время компиляции путем выбора из нескольких вариантов директив на основе признаков, определяющих условие или контекст OpenMP.
Директива declare option имеет ту же функциональность, что и метадиректива, но выбирает вариант функции в месте вызова на основе контекста или определенных пользователем условий.
Механизм, предоставляемый двумя вариантными директивами для выбора вариантов, более удобен в использовании, чем предварительная обработка C/C++, поскольку он напрямую поддерживает выбор вариантов в OpenMP и позволяет компилятору OpenMP анализировать и определять окончательную директиву из вариантов и контекста.
// адаптация кода с использованием директив предварительной обработкиint v1 [ N ], v2 [ N ], v3 [ N ]; #if defined(nvptx) #pragma omp target commands distribution parallel for map(to:v1,v2) map(from:v3) for ( int i = 0 ; i < N ; i ++ ) v3 [ i ] = v1 [ i ] * v2 [ i ]; #else #pragma omp target parallel for map(to:v1,v2) map(from:v3) for ( int i = 0 ; i < N ; i ++ ) v3 [ i ] = v1 [ i ] * v2 [ i ]; #endif// адаптация кода с использованием метадирективы в OpenMP 5.0int v1 [ N ], v2 [ N ], v3 [ N ]; #pragma omp target map(to:v1,v2) map(from:v3) #pragma omp metadirective \ when(device={arch(nvptx)}: целевые команды распределяют параллельно для)\ default(целевой параллельный для) for ( int i = 0 ; i < N ; i ++ ) v3 [ i ] = v1 [ i ] * v2 [ i ];
Положения
Поскольку OpenMP — это модель программирования с разделяемой памятью, большинство переменных в коде OpenMP по умолчанию видны всем потокам. Но иногда частные переменные необходимы для избежания условий гонки , и необходимо передавать значения между последовательной частью и параллельной областью (блок кода, выполняемый параллельно), поэтому управление средой данных вводится как предложения атрибутов совместного использования данных путем добавления их к директиве OpenMP. Различные типы предложений:
Положения атрибутов обмена данными
shared : данные, объявленные вне параллельной области, являются общими, что означает, что они видны и доступны всем потокам одновременно. По умолчанию все переменные в области разделения работы являются общими, за исключением счетчика итераций цикла.
private : данные, объявленные в параллельном регионе, являются частными для каждого потока, что означает, что каждый поток будет иметь локальную копию и использовать ее как временную переменную. Частная переменная не инициализируется, и значение не сохраняется для использования за пределами параллельного региона. По умолчанию счетчики итераций цикла в конструкциях цикла OpenMP являются частными.
default : позволяет программисту указать, что область действия данных по умолчанию в параллельном регионе будет shared , или none для C/C++, или shared , firstprivate , private , или none для Fortran. Параметр none заставляет программиста объявлять каждую переменную в параллельном регионе с использованием предложений атрибутов data sharing.
firstprivate : как private, за исключением того, что инициализируется исходным значением.
lastprivate : как private, за исключением того, что исходное значение обновляется после построения.
сокращение : безопасный способ объединения работ всех потоков после построения.
Синхронизирующие положения
критический : заключенный блок кода будет выполняться только одним потоком за раз, а не одновременно несколькими потоками. Часто используется для защиты общих данных от условий гонки .
атомарный : обновление памяти (запись или чтение-изменение-запись) в следующей инструкции будет выполнено атомарно. Это не делает весь оператор атомарным; только обновление памяти является атомарным. Компилятор может использовать специальные аппаратные инструкции для лучшей производительности, чем при использовании критических .
упорядоченный : структурированный блок выполняется в том порядке, в котором итерации будут выполняться в последовательном цикле
барьер : каждый поток ждет, пока все остальные потоки команды не достигнут этой точки. Конструкция разделения работы имеет неявную синхронизацию барьера в конце.
nowait : указывает, что потоки, завершающие назначенную работу, могут продолжать работу, не дожидаясь завершения всех потоков в команде. При отсутствии этого пункта потоки сталкиваются с барьерной синхронизацией в конце конструкции разделения работы.
Пункты расписания
schedule (type, chunk) : Это полезно, если конструкция разделения работы представляет собой do-loop или for-loop. Итерации в конструкции разделения работы назначаются потокам в соответствии с методом планирования, определенным в этом пункте. Три типа планирования:
static : Здесь всем потокам выделяются итерации до того, как они выполнят итерации цикла. Итерации по умолчанию делятся между потоками поровну. Однако указание целого числа для параметра chunk выделит количество смежных итераций chunk для конкретного потока.
dynamic : Здесь некоторые итерации выделяются меньшему числу потоков. Как только определенный поток завершает выделенную ему итерацию, он возвращается, чтобы получить еще одну из оставшихся итераций. Параметр chunk определяет количество смежных итераций, выделяемых потоку за раз.
управляемый : большой кусок смежных итераций выделяется каждому потоку динамически (как указано выше). Размер куска уменьшается экспоненциально с каждым последующим выделением до минимального размера, указанного в параметре chunk
IF-контроль
если : Это заставит потоки распараллеливать задачу только при выполнении условия. В противном случае блок кода выполняется последовательно.
Инициализация
firstprivate : данные являются частными для каждого потока, но инициализируются с использованием значения переменной с тем же именем из главного потока.
lastprivate : данные являются частными для каждого потока. Значение этих частных данных будет скопировано в глобальную переменную с тем же именем за пределами параллельной области, если текущая итерация является последней итерацией в параллельном цикле. Переменная может быть как firstprivate , так и lastprivate .
threadprivate : Данные являются глобальными данными, но они являются частными в каждом параллельном регионе во время выполнения. Разница между threadprivate и private заключается в глобальной области действия, связанной с threadprivate, и сохраненном значении в параллельных регионах.
Копирование данных
copyin : аналогично firstprivate для частных переменных, переменные threadprivate не инициализируются, если только не используется copyin для передачи значения из соответствующих глобальных переменных. Копирование не требуется, поскольку значение переменной threadprivate сохраняется на протяжении всего выполнения программы.
copyprivate : используется с single для поддержки копирования значений данных из закрытых объектов в одном потоке ( отдельном потоке) в соответствующие объекты в других потоках в группе.
Снижение
сокращение (оператор | внутренний : список) : переменная имеет локальную копию в каждом потоке, но значения локальных копий будут суммированы (сокращены) в глобальную общую переменную. Это очень полезно, если конкретная операция (указанная в операторе для этого конкретного предложения) над переменной выполняется итеративно, так что ее значение на конкретной итерации зависит от ее значения на предыдущей итерации. Шаги, которые приводят к операционному приращению, распараллеливаются, но потоки обновляют глобальную переменную потокобезопасным способом. Это потребовалось бы при распараллеливании численного интегрирования функций и дифференциальных уравнений , как общий пример.
Другие
flush : значение этой переменной восстанавливается из регистра в память для использования этого значения вне параллельной части
master : выполняется только главным потоком (потоком, который отделил все остальные во время выполнения директивы OpenMP). Неявного барьера нет; другим членам команды (потокам) не требуется достигать.
Процедуры выполнения на уровне пользователя
Используется для изменения/проверки количества потоков, определения того, находится ли контекст выполнения в параллельной области, количества процессоров в текущей системе, установки/снятия блокировок, функций синхронизации и т. д.
Переменные среды
Метод изменения функций выполнения приложений OpenMP. Используется для управления планированием итераций цикла, числом потоков по умолчанию и т. д. Например, OMP_NUM_THREADS используется для указания числа потоков для приложения.
Реализации
OpenMP реализован во многих коммерческих компиляторах. Например, Visual C++ 2005, 2008, 2010, 2012 и 2013 поддерживают его (OpenMP 2.0 в редакциях Professional, Team System, Premium и Ultimate [20] [21] [22] ), а также Intel Parallel Studio для различных процессоров. [23] Компиляторы и инструменты Oracle Solaris Studio поддерживают новейшие спецификации OpenMP с улучшениями производительности для платформ Solaris OS (UltraSPARC и x86/x64) и Linux. Компиляторы Fortran, C и C++ от The Portland Group также поддерживают OpenMP 2.5. GCC также поддерживает OpenMP с версии 4.2.
Компиляторы с реализацией OpenMP 3.0:
ССЗ 4.3.1
Компилятор Меркурия
Компиляторы Intel Fortran и C/C++ версий 11.0 и 11.1, Intel C/C++ и Fortran Composer XE 2011 и Intel Parallel Studio.
Компилятор IBM XL [24]
Sun Studio 12 update 1 имеет полную реализацию OpenMP 3.0 [25]
Многопроцессорные вычисления
Несколько компиляторов поддерживают OpenMP 3.1:
ССЗ 4.7 [26]
Компиляторы Intel Fortran и C/C++ 12.1 [27]
Компиляторы IBM XL C/C++ для AIX и Linux, V13.1 [28] и компиляторы IBM XL Fortran для AIX и Linux, V14.1 [29]
Allinea MAP – профилировщик для кодов OpenMP и MPI
TotalView — отладчик от Rogue Wave Software для OpenMP, MPI и последовательных кодов
ompP – профайлер для OpenMP
VAMPIR – профайлер для кода OpenMP и MPI
Плюсы и минусы
Плюсы:
Переносимый многопоточный код (в C/C++ и других языках для реализации многопоточности обычно приходится вызывать платформенно-специфичные примитивы).
Просто: не нужно заниматься передачей сообщений, как это делает MPI .
Компоновка и декомпозиция данных выполняется автоматически с помощью директив.
Масштабируемость сопоставима с MPI в системах с общей памятью. [39]
Инкрементный параллелизм: может работать над одной частью программы одновременно, не требуется кардинальных изменений в коде.
Унифицированный код для последовательных и параллельных приложений: конструкции OpenMP обрабатываются как комментарии при использовании последовательных компиляторов.
Исходные (последовательные) операторы кода, как правило, не нуждаются в модификации при распараллеливании с помощью OpenMP. Это снижает вероятность непреднамеренного внесения ошибок.
В нерегулярных мультифизических приложениях, которые не придерживаются исключительно режима вычислений SPMD , как это происходит в тесно связанных системах жидкость-частицы, гибкость OpenMP может иметь большое преимущество в производительности по сравнению с MPI . [39] [40]
Может использоваться на различных ускорителях, таких как GPGPU [41] и FPGA .
Минусы:
Риск появления трудноотлаживаемых ошибок синхронизации и состояний гонки . [42] [43]
По состоянию на 2017 год [обновлять]эффективно работает только на многопроцессорных платформах с общей памятью (см., однако, Intel Cluster OpenMP, архив 2018-11-16 на Wayback Machine и другие распределенные платформы с общей памятью).
Отсутствуют механизмы точного управления сопоставлением потоков и процессоров.
Высокая вероятность случайного написания ложного кода совместного использования.
Ожидания производительности
Можно было бы ожидать ускорения в N раз при запуске программы, распараллеленной с помощью OpenMP на платформе процессоров N. Однако это происходит редко по следующим причинам:
При наличии зависимости процесс должен дождаться, пока будут вычислены данные, от которых он зависит.
Когда несколько процессов совместно используют ресурс непараллельного доказательства (например, файл для записи), их запросы выполняются последовательно. Поэтому каждый поток должен ждать, пока другой поток не освободит ресурс.
Значительная часть программы не может быть распараллелена OpenMP, что означает, что теоретический верхний предел ускорения ограничен законом Амдаля .
N процессоров в симметричной многопроцессорной обработке (SMP) могут иметь в N раз большую вычислительную мощность, но пропускная способность памяти обычно не масштабируется в N раз. Довольно часто исходный путь памяти совместно используется несколькими процессорами, и может наблюдаться ухудшение производительности, когда они конкурируют за общую пропускную способность памяти.
Многие другие распространенные проблемы, влияющие на конечное ускорение параллельных вычислений, также применимы к OpenMP, например, балансировка нагрузки и накладные расходы на синхронизацию.
Оптимизация компилятора может быть не столь эффективной при вызове OpenMP. Это может обычно приводить к тому, что однопоточная программа OpenMP будет работать медленнее, чем тот же код, скомпилированный без флага OpenMP (который будет полностью последовательным).
Сродство потока
Некоторые поставщики рекомендуют устанавливать соответствие процессора потокам OpenMP, чтобы связать их с определенными ядрами процессора. [45] [46] [47]
Это минимизирует миграцию потоков и стоимость переключения контекста между ядрами. Это также улучшает локальность данных и снижает трафик когерентности кэша между ядрами (или процессорами).
Показатели
Разработан ряд тестов для демонстрации использования OpenMP, тестирования его производительности и оценки корректности.
Простые примеры
OmpSCR: репозиторий исходного кода OpenMP
Показатели производительности включают в себя:
Параллельный тест NAS
Barcelona OpenMP Task Suite — набор приложений, позволяющих тестировать реализации задач OpenMP.
серия СПЕЦ
СПЕЦ ОМП 2012
Тестовый набор SPEC ACCEL для тестирования API разгрузки целевых объектов OpenMP 4
Тест SPEChpc 2002
Показатели CORAL
Exascale прокси-приложения
«Родиния» делает ставку на ускорители.
Проблемно-ориентированный набор эталонных тестов
Тесты корректности включают в себя:
Пакет проверки OpenMP
Тестовый набор для проверки и верификации OpenMP
DataRaceBench — это набор тестов, предназначенный для систематической и количественной оценки эффективности инструментов обнаружения гонки данных OpenMP.
AutoParBench — это набор тестов для оценки компиляторов и инструментов, которые могут автоматически вставлять директивы OpenMP.
^ ab "OpenMP Compilers & Tools". OpenMP.org. Ноябрь 2019 г. Получено 2020-03-05 .
^ ab Gagne, Abraham Silberschatz, Peter Baer Galvin, Greg (2012-12-17). Концепции операционной системы (9-е изд.). Hoboken, NJ: Wiley. стр. 181–182. ISBN978-1-118-06333-0.{{cite book}}: CS1 maint: несколько имен: список авторов ( ссылка )
^ Учебник OpenMP на Supercomputing 2008
^ Использование OpenMP – Переносимое параллельное программирование с общей памятью – Загрузите примеры книги и обсудите
^ Коста, Дж. Дж. и др. (Май 2006 г.). «Эффективный запуск приложений OpenMP на SDSM с общим доступом». Журнал параллельных и распределенных вычислений . 66 (5): 647–658. doi :10.1016/j.jpdc.2005.06.018. hdl : 2117/370260 .
^ Basumallik, Ayon; Min, Seung-Jai; Eigenmann, Rudolf (2007). «Программирование распределенных систем памяти с использованием OpenMP». 2007 IEEE International Parallel and Distributed Processing Symposium . Нью-Йорк: IEEE Press. стр. 1–8. CiteSeerX 10.1.1.421.8570 . doi :10.1109/IPDPS.2007.370397. ISBN978-1-4244-0909-9. S2CID 14237507.Препринт доступен на домашней странице Чэнь Дина; особенно см. Раздел 3 о переводе OpenMP в MPI.
^ Ван, Цзюэ; Ху, Чанцзюнь; Чжан, Цзилинь; Ли, Цзяньцзян (май 2010 г.). «Компилятор OpenMP для архитектур с распределенной памятью». Science China Information Sciences . 53 (5): 932–944. doi : 10.1007/s11432-010-0074-0 .(По состоянию на 2016 год [обновлять]программное обеспечение KLCoMP, описанное в этой статье, по-видимому, не является общедоступным)
^
Cluster OpenMP (продукт, который был доступен для Intel C++ Compiler версий 9.1–11.1, но был исключен из 13.0)
^ Айгуаде, Эдуард; Копти, Навал; Дюран, Алехандро; Хёфлингер, Джей; Линь, Юань; Массайоли, Федерико; Су, Эрнесто; Унникришнан, Прия; Чжан, Гуансонг (2007). Предложение по параллелизму задач в OpenMP (PDF) . Труды Международного семинара по OpenMP.
^ "OpenMP Application Program Interface, Version 3.0" (PDF) . openmp.org. Май 2008 . Получено 2014-02-06 .
^ ЛаГрон, Джеймс; Арибуки, Айодунни; Аддисон, Коди; Чепмен, Барбара (2011). Реализация задач OpenMP во время выполнения . Учеб. Международный семинар по OpenMP. стр. 165–178. CiteSeerX 10.1.1.221.2775 . дои : 10.1007/978-3-642-21487-5_13.
^ "OpenMP 4.0 API Released". OpenMP.org. 2013-07-26. Архивировано из оригинала 2013-11-09 . Получено 2013-08-14 .
^ "OpenMP Application Program Interface, Version 4.0" (PDF) . openmp.org. Июль 2013 . Получено 2014-02-06 .
^ «Спецификация OpenMP 5.2».
^ «OpenMP ARB выпускает технический отчет 12».
^ «C — Как использовать printf() в нескольких потоках».
^ "std::cout, std::wcout - cppreference.com".
^ "Учебник – Параллельные циклы с OpenMP". 2009-07-14.
^ Редакции Visual C++, Visual Studio 2005
^ Редакции Visual C++, Visual Studio 2008
^ Редакции Visual C++, Visual Studio 2010
^ Дэвид Уортингтон, «Intel решает проблемы жизненного цикла разработки с помощью Parallel Studio». Архивировано 15 февраля 2012 г. на Wayback Machine , SDTimes, 26 мая 2009 г. (дата обращения 28 мая 2009 г.)
^ "XL C/C++ for Linux Features", (дата обращения: 9 июня 2009 г.)
^ "Oracle Technology Network для разработчиков Java | Oracle Technology Network | Oracle". Developers.sun.com . Получено 14 августа 2013 г.
Куинн Майкл Дж., Параллельное программирование на языке C с использованием MPI и OpenMP McGraw-Hill Inc. 2004. ISBN 0-07-058201-7
Р. Чандра, Р. Менон, Л. Дагум, Д. Кор, Д. Мэйдан, Дж. Макдональд, Параллельное программирование в OpenMP. Морган Кауфманн, 2000. ISBN 1-55860-671-8.
R. Eigenmann (редактор), M. Voss (редактор), OpenMP Shared Memory Parallel Programming: International Workshop on OpenMP Applications and Tools, WOMPAT 2001, West Lafayette, IN, USA, 30–31 июля 2001 г. (Конспект лекций по информатике). Springer 2001. ISBN 3-540-42346-X
B. Chapman, G. Jost, R. van der Pas, DJ Kuck (предисловие), Использование OpenMP: Портативное параллельное программирование с общей памятью. MIT Press (31 октября 2007 г.). ISBN 0-262-53302-2
Том Дикин и Тимоти Г. Мэттсон: Программирование графического процессора с помощью OpenMP: переносимость производительности для графических процессоров , The MIT Press, ISBN 978-0-262547536 (7 ноября 2023 г.).
Параллельная обработка через MPI и OpenMP, М. Фирузиан, О. Номменсен. Linux Enterprise, 10/2002
Статья в журнале MSDN Magazine об OpenMP
Учебное пособие по OpenMP SC08, архив 2013-03-19 на Wayback Machine (PDF) – Практическое введение в OpenMP, Мэттсон и Медоуз, от SC08 (Остин)
Спецификации OpenMP Архивировано 2021-03-02 на Wayback Machine
Мигель Херманнс: Параллельное программирование на языке Fortran 95 с использованием OpenMP (19 апреля 2002 г.) (PDF) (OpenMP версии 1 и 2)