Разработка спецификаций стандарта ведётся некоммерческой организацией OpenMP Architecture Review Board (ARB)[1], в которую входят все основные производители процессоров, а также ряд суперкомпьютерных лабораторий и университетов. Первая версия спецификации вышла в 1997 году, предназначалась только для Фортрана, в следующем году вышла версия для Си и C++.
Задачи, выполняемые потоками параллельно, так же, как и данные, требуемые для выполнения этих задач, описываются с помощью специальных директив препроцессора соответствующего языка — «прагм». Например, участок кода на
Фортране, который должен исполняться несколькими потоками, каждый из которых имеет свою копию переменной N, предваряется следующей директивой: !$OMP PARALLEL PRIVATE(N)
Количество создаваемых потоков может регулироваться как самой программой при помощи вызова библиотечных процедур, так и извне, при помощи переменных окружения.
Ключевые элементы стандарта:
конструкции для создания потоков (директива parallel),
конструкции распределения работы между потоками (директивы DO/for и section),
конструкции для управления работой с данными (выражения shared и private для определения класса памяти переменных),
конструкции для синхронизации потоков (директивы critical, atomic и barrier),
процедуры библиотеки поддержки времени выполнения (например, omp_get_thread_num),
Программа на Фортране-77, создающая заранее неизвестное число потоков (оно определяется переменной окружения OMP_NUM_THREADS перед запуском программы), каждый из которых выводит приветствие вместе со своим номером; ведущий поток (имеющий номер 0) также выводит общее число потоков, но только после того, как все они «пройдут» директиву BARRIER:
PROGRAM HELLOINTEGER ID,NTHRDSINTEGER OMP_GET_THREAD_NUM,OMP_GET_NUM_THREADSC$OMPPARALLELPRIVATE(ID)ID=OMP_GET_THREAD_NUM()PRINT*,'HELLO WORLD FROM THREAD',IDC$OMPBARRIERIF(ID.EQ.0)THENNTHRDS=OMP_GET_NUM_THREADS()PRINT*,'THERE ARE',NTHRDS,'THREADS'END IFC$OMPEND PARALLELEND
Программа на Си, складывающая в десять потоков массив a с массивом b (компилируется с использованием gcc-4.4 и более новых версий с флагом -fopenmp):
#include<stdio.h>#include<omp.h>#define N 100intmain(intargc,char*argv[]){doublea[N],b[N],c[N];inti;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[10]);return0;}
Реализации
OpenMP поддерживается многими современными компиляторами.
Компиляторы Sun Studio поддерживают спецификацию OpenMP 2.5[2] с поддержкой операционной системы Solaris; поддержка Linux запланирована на следующий выпуск[уточнить]. Эти компиляторы создают отдельную процедуру из исходного кода, располагающегося под директивой parallel, а вместо самой директивы вставляют вызов процедуры __mt_MasterFunction_ библиотеки libmtsk, передавая ей адрес искусственно созданной. Таким образом, разделяемые (shared) данные могут быть переданы последней по ссылке, а собственные (private) объявляются внутри этой процедуры, оказываясь независимыми от своих копий в других потоках. Процедура __mt_MasterFunction_ создает группу потоков (количеством 9 в приведенном выше примере на языке C), которые будут выполнять код конструкции parallel, а вызвавший её поток становится главным в группе. Затем главный поток организовывает работу подчиненных потоков, после чего начинает выполнять пользовательский код сам. Когда код будет выполнен, главный поток вызывает процедуру _mt_EndOfTask_Barrier_, синхронизирующую его с остальными.
Visual C++ 2005 и 2008 поддерживает OpenMP 2.0 в редакциях Professional и Team System, 2010 — в редакциях Professional, Premium и Ultimate, 2012 — во всех редакциях[3].
В GCC начиная с версии 4.2 реализована поддержка OpenMP для Си, C++ и Фортрана (на базе gfortran), а некоторые дистрибутивы (такие как Fedora Core 5) включили поддержку в GCC 4.1. В Clang и LLVM 3.7 поддерживается OpenMP 3.1.[4].
Intel C++ Compiler, Intel Fortran Compiler и Intel Parallel Studio поддерживают версию OpenMP 3.0, а также Intel Cluster OpenMP для программирования в системах с распределённой памятью. Существуют также реализации в компиляторах IBM XL compiler, PGI (Portland group), Pathscale, HP[уточнить].