OpenMP (Open Multi-Processing) — открытый стандарт для распараллеливания программ на языках Си, C++ и Фортран. Даёт описание совокупности директив компилятора, библиотечных процедур и переменных окружения, которые предназначены для программирования многопоточных приложений на многопроцессорных системах с общей памятью.

Разработка спецификаций стандарта ведётся некоммерческой организацией OpenMP Architecture Review Board (ARB), в которую входят все основные производители процессоров, а также ряд суперкомпьютерных лабораторий и университетов. Первая версия спецификации вышла в 1997 году, предназначалась только для Фортрана, в следующем году вышла версия для Си и C++.

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

Задачи, выполняемые потоками параллельно, так же, как и данные, требуемые для выполнения этих задач, описываются с помощью специальных директив препроцессора соответствующего языка — «прагм». Например, участок кода на Фортране, который должен исполняться несколькими потоками, каждый из которых имеет свою копию переменной N, предваряется следующей директивой: !$OMP PARALLEL PRIVATE(N)

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

Ключевые элементы стандарта: конструкции для создания потоков (директива parallel), конструкции распределения работы между потоками (директивы DO/for и section), конструкции для управления работой с данными (выражения shared и private для определения класса памяти переменных), конструкции для синхронизации потоков (директивы critical, atomic и barrier), процедуры библиотеки поддержки времени выполнения (например, omp_get_thread_num), переменные окружения (например, OMP_NUM_THREADS).

Примеры Программа на Фортране-77, создающая заранее неизвестное число потоков (оно определяется переменной окружения OMP_NUM_THREADS перед запуском программы), каждый из которых выводит приветствие вместе со своим номером; ведущий поток (имеющий номер 0) также выводит общее число потоков, но только после того, как все они «пройдут» директиву BARRIER: PROGRAM HELLO INTEGER ID, NTHRDS INTEGER OMP_GET_THREAD_NUM, OMP_GET_NUM_THREADS C$OMP PARALLEL PRIVATE(ID) ID = OMP_GET_THREAD_NUM() PRINT *, 'HELLO WORLD FROM THREAD', ID C$OMP BARRIER IF ( ID .EQ. 0 ) THEN NTHRDS = OMP_GET_NUM_THREADS() PRINT *, 'THERE ARE', NTHRDS, 'THREADS' END IF C$OMP END PARALLEL END

Программа на Си, складывающая в десять потоков массив a с массивом b (компилируется с использованием gcc-4.4 и более новых версий с флагом -fopenmp): #include <stdio.h> #include <omp.h>

#define N 100

int main(int argc, char *argv[]) { double a[N], b[N], c[N]; int i; omp_set_dynamic(0); // запретить библиотеке openmp менять число потоков во время исполнения omp_set_num_threads(10); // установить число потоков в 10

// инициализируем массивы for (i = 0; i < N; i++)

a[i] = i * 1.0; b[i] = i * 2.0;

// вычисляем сумму массивов #pragma omp parallel for shared(a, b, c) private(i) for (i = 0; i < N; i++) c[i] = a[i] + b[i];

printf("%f\n", c); return 0; }

Реализации OpenMP поддерживается многими современными компиляторами.

Компиляторы Sun Studio поддерживают спецификацию OpenMP 2.51. Introducing the OpenMP API (Sun Studio 12: OpenMP API User’s Guide) — Sun Microsystems с поддержкой операционной системы Solaris; поддержка Linux запланирована на следующий выпуск. Эти компиляторы создают отдельную процедуру из исходного кода, располагающегося под директивой parallel, а вместо самой директивы вставляют вызов процедуры __mt_MasterFunction_ библиотеки libmtsk, передавая ей адрес искусственно созданной. Таким образом, разделяемые () данные могут быть переданы последней по ссылке, а собственные () объявляются внутри этой процедуры, оказываясь независимыми от своих копий в других потоках. Процедура __mt_MasterFunction_ создает группу потоков (количеством 9 в приведенном выше примере на языке C), которые будут выполнять код конструкции parallel, а вызвавший её поток становится главным в группе. Затем главный поток организовывает работу подчиненных потоков, после чего начинает выполнять пользовательский код сам. Когда код будет выполнен, главный поток вызывает процедуру _mt_EndOfTask_Barrier_, синхронизирующую его с остальными.

Visual C++ 2005 и 2008 поддерживает OpenMP 2.0 в редакциях Professional и Team System, 2010 — в редакциях Professional, Premium и Ultimate, 2012 — во всех редакциях.

В GCC начиная с версии 4.2 реализована поддержка OpenMP для Си, C++ и Фортрана (на базе gfortran), а некоторые дистрибутивы (такие как Fedora Core 5) включили поддержку в GCC 4.1. В Clang и LLVM 3.7 поддерживается OpenMP 3.1..

Intel C++ Compiler, Intel Fortran Compiler и Intel Parallel Studio поддерживают версию OpenMP 3.0, а также Intel Cluster OpenMP для программирования в системах с распределённой памятью. Существуют также реализации в компиляторах IBM XL compiler, PGI (Portland group), Pathscale, HP.

См. также Intel Threading Building Blocks — библиотека для параллельного программирования на C++ MPI (Message Passing Interface) — интерфейс обмена сообщений между процессами OpenCL — открытый каркас для параллельных вычислений на графических и центральных процессорах OpenACC

Примечания

Ссылки

Intel Software Network

viva64.com Статья «32 подводных камня OpenMP при программировании на Си++» Статья «Отладка и оптимизация многопоточных OpenMP-программ» Другие источники Учебник по OpenMP Введение в OpenMP: API параллельных программ для многопроцессорных систем с общей памятью Что такое OpenMP?  — базовая статья на сайте parallel.ru OpenMP и C++ Параллельное программирование с использованием OpenMP  — Учебный курс на сайте Intuit.ru Презентация на тему OpenMP OpenMP Support in Sun Studio Compilers and Tools

Категория:Библиотеки C++ Категория:Параллельные вычисления Категория:Библиотеки параллельного программирования Категория:Статьи с примерами кода на Фортране