OpenMP

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку
OpenMP
OpenMP logo
Тип прикладний програмний інтерфейс
Автор OpenMP Architecture Review Board[1]
Розробник OpenMP Architecture Review Board[1]
Стабільний випуск 4.0[2] (23 липня 2013; 10 років тому (2013-07-23))
Платформа крос-платформовий
Операційна система крос-платформовий
Мова програмування C, C++, Fortran
Ліцензія різні[3]
Вебсайт openmp.org

CMNS: OpenMP у Вікісховищі

OpenMP (Open Multi-Processing) — це набір директив компілятора, бібліотечних процедур та змінних середовища, які призначені для програмування багатопоточних застосунків на багатопроцесорних системах із спільною пам'яттю на мовах C, C++ та Fortran.

Розробку специфікації OpenMP ведуть кілька великих виробників обчислювальної техніки та програмного забезпечення, робота яких регулюється некомерційною організацією, названою OpenMP Architecture Review Board (ARB)[4]. Детальна специфікація OpenMP міститься на сторінці [Архівовано 24 квітня 2008 у Wayback Machine.]. Специфікації для мов Fortran і C/C++ з'явилися відповідно в жовтні 1997 року і жовтні 1998 року.

Опис[ред. | ред. код]

OpenMP можна розглядати як високорівневу надбудову над Pthreads (або аналогічними бібліотеками потоків). POSIX-інтерфейс для організації потоків Pthreads підтримується широко (практично на всіх UNIX-системах), проте з багатьох причин не підходить для практичного паралельного програмування:

  1. немає підтримки Fortran
  2. дуже низький рівень
  3. немає підтримки паралелізму за даними
  4. механізм нитей спочатку розроблявся не для цілей організації паралелізму

OpenMP реалізує паралельні обчислення за допомогою багатопотоковості, в якій «головний» (master) потік створює набір підлеглих (slave) потоків і завдання розподіляється між ними. Передбачається, що потоки виконуються паралельно на машині з декількома процесорами (кількість процесорів не обов'язково має бути більше або дорівнювати кількості потоків).

Завдання, що виконуються потоками паралельно, так само як і дані, необхідні для виконання цих завдань, описуються за допомогою спеціальних директив препроцесора відповідної мови — прагм. Наприклад, ділянка коду на мові Fortran, яка повинна виконуватися кількома потоками, кожна з яких має свою копію змінної N, передує наступній !$OMP PARALLEL PRIVATE(N)

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

Переваги[ред. | ред. код]

  1. За рахунок ідеї «інкрементального розпаралелювання» OpenMP ідеально підходить для розробників, що прагнуть швидко розпаралелювати свої обчислювальні програми з великими паралельними циклами. Розробник не створює нову паралельну програму, а просто послідовно додає в текст програми OpenMP-директиви.
  2. При цьому, OpenMP — досить гнучкий механізм, що надає розробникові великі можливості контролю над поведінкою паралельної програми.
  3. Передбачається, що OpenMP-програма на однопроцесорній платформі може бути використана як послідовна програма, тобто немає необхідності підтримувати послідовну та паралельну версії. Директиви OpenMP просто ігноруються послідовним компілятором, а для виклику процедур OpenMP можуть бути підставлені заглушки (stubs), текст яких приведений в специфікаціях.
  4. Однією з переваг 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[5]

Visual C++ 2005 підтримує OpenMP у редакціях Professional і Team System[6].

GCC 4.2 підтримує OpenMP 2.5, а деякі дистрибутиви (такі як Fedora Core 5 gcc [Архівовано 20 травня 2007 у Wayback Machine.]) включили підтримку в свої версії GCC 4.1. Починаючи з GCC 4.4 підтримується стандарт OpenMP 3.0 а з версії GCC 4.7 — OpenMP 3.1[7]

В універсальному комплексі Intel Parallel Studio від Intel об'єднано компілятори C++ та Фортран, бібліотеки оптимізації та паралелізації, включаючи OpenMP 3.1 (починаючи з версії компіляторів 12.1), а також засоби перевірки помилок та продуктивності, зневаджувач і профайлер для останніх поколінь багатоядерних процесорів.

Приклад реалізації[ред. | ред. код]

Компілятори Sun Studio створюють окрему процедуру з вихідного коду, розташованого під директивою parallel, а замість самої директиви вставляють виклик процедури __mt_MasterFunction_ бібліотеки libmtsk, передаючи їй адресу штучно створену. Таким чином, розподілювані (shared) дані можуть бути передані останній за посиланням, а власні (private) оголошуються всередині цієї процедури, опиняючись незалежні від своїх копій в інших нитях.

Процедура __mt_MasterFunction_ створює групу нитей (кількістю 9 у наведеному вище прикладі на мові C), які будуть виконувати код конструкції parallel, а нить, що викликала їх, стає головною у групі. Потім головна нить організовує роботу підлеглих нитей, після чого починає виконувати код користувача сама. Коли код буде виконаний, головна нить викликає процедуру _mt_EndOfTask_Barrier_ що синхронізує її з іншими.

Інструменти[ред. | ред. код]

  • VivaMP — Статичний аналізатор Сі/Сі++ коду для виявлення помилок в програмах, побудованих на технології OpenMP для ОС Windows.

Примітки[ред. | ред. код]

  1. а б http://openmp.org/wp/about-openmp/ [Архівовано 9 серпня 2013 у Wayback Machine.] About the OpenMP ARB and OpenMP.org
  2. http://openmp.org/wp/2013/07/openmp-40/ [Архівовано 23 серпня 2013 у Wayback Machine.] OpenMP 4.0 Specification Released
  3. http://openmp.org/wp/openmp-compilers/ [Архівовано 17 липня 2013 у Wayback Machine.] OpenMP Compilers
  4. Офіційний сайт OpenMP Architecture Review Board. Архів оригіналу за 20 липня 2008. Процитовано 3 червня 2009. 
  5. Oracle Solaris Studio 12.3 OpenMP API User's Guide, PDF. Архів оригіналу за 16 травня 2013. Процитовано 3 вересня 2012. 
  6. MSDN: Visual C++ Editions. Архів оригіналу за 23 квітня 2008. Процитовано 3 червня 2009. 
  7. GCC Wiki OpenMP. Архів оригіналу за 17 вересня 2012. Процитовано 3 вересня 2012. 

Посилання[ред. | ред. код]