OpenMP
OpenMP (Open Multi-Processing) — це набір директив компілятора, бібліотечних процедур та змінних середовища, які призначені для програмування багатонитевих застосунків на багатопроцесорних системах із спільною пам'яттю на мовах C, C++ та Fortran.
Розробку специфікації OpenMP ведуть кілька великих виробників обчислювальної техніки та програмного забезпечення, робота яких регулюється некомерційною організацією, названою OpenMP Architecture Review Board (ARB)[1]. Детальна специфікація OpenMP міститься на сторінці. Специфікації для мов Fortran і C/C++ з'явилися відповідно в жовтні 1997 року і жовтні 1998 року.
Зміст |
Опис [ред.]
OpenMP можна розглядати як високорівневу надбудову над Pthreads (або аналогічними бібліотеками нитей). POSIX-інтерфейс для організації нитей Pthreads підтримується широко (практично на всіх UNIX-системах), проте з багатьох причин не підходить для практичного паралельного програмування:
- немає підтримки Fortran
- дуже низький рівень
- немає підтримки паралелізму за даними
- механізм нитей спочатку розроблявся не для цілей організації паралелізму
OpenMP реалізує паралельні обчислення за допомогою багатонитевості, в якій «головна» (master) нить створює набір підлеглих (slave) нитей і завдання розподіляється між ними. Передбачається, що ниті виконуються паралельно на машині з декількома процесорами (кількість процесорів не обов'язково має бути більше або дорівнювати кількості нитей).
Завдання, що виконуються нитями паралельно, так само як і дані, необхідні для виконання цих завдань, описуються за допомогою спеціальних директив препроцесора відповідної мови — прагм. Наприклад, ділянка коду на мові Fortran, яка повинна виконуватися кількома нитями, кожна з яких має свою копію змінної N, передує наступній !$OMP PARALLEL PRIVATE(N)
Кількість створюваних нитей може регулюватися як самою програмою за допомогою виклику бібліотечних процедур, так і ззовні, за допомогою змінних оточення.
Переваги [ред.]
- За рахунок ідеї «інкрементального розпаралелювання» OpenMP ідеально підходить для розробників, що прагнуть швидко розпаралелювати свої обчислювальні програми з великими паралельними циклами. Розробник не створює нову паралельну програму, а просто послідовно додає в текст програми OpenMP-директиви.
- При цьому, OpenMP — досить гнучкий механізм, що надає розробникові великі можливості контролю над поведінкою паралельного застосунку.
- Передбачається, що OpenMP-програма на однопроцесорній платформі може бути використана як послідовна програма, тобто немає необхідності підтримувати послідовну та паралельну версії. Директиви OpenMP просто ігноруються послідовним компілятором, а для виклику процедур OpenMP можуть бути підставлені заглушки (stubs), текст яких приведений в специфікаціях.
- Однією з переваг OpenMP розробники вважають підтримку так званих «orphan» (відірваних) директив, тобто директиви синхронізації і розподілу роботи можуть не входити безпосередньо в лексичний контекст паралельної області.
Ключові елементи [ред.]
Ключовими елементами OpenMP є
- конструкції для створення нитей (директива parallel),
- конструкції розподілу роботи між нитями (директиви DO / for та section),
- конструкції для керування роботою з даними (вираз shared і private),
- конструкції для синхронізації нитей (директиви critical atomic і barrier),
- процедури бібліотеки підтримки часу виконанню (наприклад, omp_get_thread_num),
- змінні оточення (наприклад, OMP_NUM_THREADS).
Приклади програм [ред.]
Нижче наведені приклади програм з використанням директив OpenMP:
C [ред.]
У цій програмі два вектора (a і b) додаються паралельно десятьма нитями.
#include <stdio.h> #include <omp.h> #define N 100 int main(int argc, char *argv[]) { float a[N], b[N], c[N]; int i; omp_set_dynamic(0); // заборонити змінювати число нитей за допомогою змінної оточення 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 shared(a, b, c) private(i) { #pragma omp for for (i = 0; i < N; i++) c[i] = a[i] + b[i]; } printf ("%f\n", c[10]); return 0; }
Fortran [ред.]
Аналогічна програма на мові Фортран
program main use omp_lib implicit none integer, parameter :: rp = kind(1.0) integer, parameter :: N=100 real(rp), dimension(1:N) :: a,b,c integer :: i call omp_set_dynamic(.false.) ! заборонити змінювати число нитей за допомогою змінної оточення call omp_set_num_threads(10) ! встановити число нитей у 10 ! ініціалізуємо вектори do i=1,N a(i)=i*1.0_rp b(i)=i*2.0_rp enddo ! обчислюємо суму векторів !$omp parallel do shared(a, b, c) private(i) do i=1,N c(i)=a(i)+b(i) enddo !$omp end parallel do write(*,'(f10.6)') c(10) end program main
Існуючі реалізації [ред.]
OpenMP підтримується багатьма комерційними компіляторами.
Компілятори Oracle Solaris Studio, v12.3, підтримують офіційно специфікацію OpenMP 3.1 — з покращеною продуктивністю під ОС Solaris та обмеженим числом платформ під ОС Linux [2]
Visual C++ 2005 підтримує OpenMP у редакціях Professional і Team System[3].
GCC 4.2 підтримує OpenMP 2.5, а деякі дистрибутиви (такі як Fedora Core 5 gcc) включили підтримку в свої версії GCC 4.1. Починаючи з GCC 4.4 підтримується стандарт OpenMP 3.0 а з версії GCC 4.7 - OpenMP 3.1 [4]
В універсальному комплексі Intel Parallel Studio від Intel об'єднано компілятори C++ та Фортран, бібліотеки оптимізації та паралелізації, включаючи OpenMP 3.1 (починаючи з версії компіляторів 12.1), а також засоби перевірки помилок та продуктивності, зневаджувач i профайлер для останніх поколінь багатоядерних процесорів.
Приклад реалізації [ред.]
Компілятори Sun Studio створюють окрему процедуру з вихідного коду, розташованого під директивою parallel, а замість самої директиви вставляють виклик процедури __mt_MasterFunction_ бібліотеки libmtsk, передаючи їй адресу штучно створену. Таким чином, розподілювані (shared) дані можуть бути передані останній за посиланням, а власні (private) оголошуються всередині цієї процедури, опиняючись незалежні від своїх копій в інших нитях.
Процедура __mt_MasterFunction_ створює групу нитей (кількістю 9 у наведеному вище прикладі на мові C), які будуть виконувати код конструкції parallel, а нить, що викликала їх, стає головною у групі. Потім головна нить організовує роботу підлеглих нитей, після чого починає виконувати код користувача сама. Коли код буде виконаний, головна нить викликає процедуру _mt_EndOfTask_Barrier_ що синхронізує іі з іншими.
Інструменти [ред.]
- VivaMP — Статичний аналізатор Сі/Сі++ коду для виявлення помилок в програмах, побудованих на технології OpenMP для ОС Windows.
Виноски [ред.]
Посилання [ред.]
- OpenMP.org — Офіційний сайт OpenMP Architecture Review Board
- Что такое OpenMP? (рос.)
- Введение в OpenMP: API параллельных программ для многопроцессорных систем с общей памятью (рос.)
- OpenMP и C++ (рос.)
- Учебный курс — Параллельное программирование с использованием OpenMP (рос.)
- OpenMP Support in Sun Studio Compilers and Tools (англ.)
- Статья «32 подводных камня OpenMP при программировании на Си++» (рос.)
|
||||||||||||||||||||||||||||||||
