﻿# Параллельные заметки N1 – технология OpenMP

В ближайшие несколько постов мы расскажем о практическом использовании многоядерных процессоров\. Ведь все\-таки что бы ни говорилось о многоядерности, в любом случае программы надо "обучать" эффективному использованию нескольких ядер\. А в этом первом посте будет анонс и первая "вводная" заметка\.

![0053_Parallel_notes_N1_-_OpenMP_technology_ru/image1.png](https://import.viva64.com/docx/blog/0053_Parallel_notes_N1_-_OpenMP_technology_ru/image1.png)

## Технологии параллельного программирования

Сразу же надо сказать, что существует довольно много разных технологий параллельного программирования\. Причем эти технологии отличаются не только и не столько языками программирования, сколько архитектурными подходами к построению параллельных систем\.

Например, какие\-то технологии предполагают построение параллельных решений на основе нескольких компьютеров \(как одного, так и разных типов\), другие же предполагают именно работу на одной машине с несколькими процессорными ядрами\.

Системы на базе нескольких компьютеров относят к классу систем для распределенных вычислений\. Подобные решения используются довольно давно, их хорошо понимают профессионалы индустрии, по ним имеется довольно много литературы\. Наиболее яркий пример технологии распределенных вычислений \- [MPI](https://pvs-studio.ru/ru/blog/terms/0032/) \(Message Passing Interface \- интерфейс передачи сообщений\)\. MPI является наиболее распространённым стандартом интерфейса обмена данными в параллельном программировании, существуют его реализации для большого числа компьютерных платформ\. MPI предоставляет программисту единый механизм взаимодействия ветвей внутри параллельного приложения независимо от машинной архитектуры \(однопроцессорные/многопроцессорные с общей/раздельной памятью\), взаимного расположения ветвей \(на одном процессоре или на разных\)\.

Так как MPI предназначен для систем с раздельной памятью, то использовать его для организации параллельного процесса в системе с общей памятью не лучшая идея\. Это будет слишком избыточно и сложно, поэтому\-то и начали развиваться решения вроде OpenMP\. Хотя, конечно же, ничто не мешает делать MPI\-решения для одной машины\.

А вот системы параллельного программирования для работы на одной машине, начали развиваться относительно недавно\. Нет, конечно же, не стоит думать, что это принципиально новые идеи, но именно с приходом \(вернее с предстоящим приходом\) многоядерных систем на рабочий стол, программистам стоит обратить свое внимание на такие технологии как [OpenMP](https://pvs-studio.ru/ru/blog/terms/0037/), [Intel Thread Building Blocks](https://github.com/oneapi-src/onetbb), [Microsoft Parallel Extensions](https://en.wikipedia.org/wiki/Parallel_Extensions)  и ряд других\.

Очень важно, чтобы технология параллельного программирования поддерживала возможность делать программу параллельной постепенно\. Да, понятно, что идеальную параллельную программу надо сразу писать параллельной, а еще лучше на каком\-нибудь функциональном языке, где вопрос распараллеливания вообще не стоит\.\.\. Но программисты живут и работают в реальном мире, в котором вместо новомодного функционального F\#  есть 10 МБайт кода в лучшем случае на C\+\+, а то и вообще на C\. И этот код надо постепенно распараллеливать\. В этом случае технология OpenMP \(к примеру\) будет очень удачным выбором\. Она позволяет, выбрав в приложении наиболее нуждающиеся в параллелизации места, в первую очередь сделать параллельными именно их\. На практике это выглядит так\. С помощью какого\-либо инструмента для профилирования программист ищет в программе "узкие места", которые работают наиболее долго\. Почему с помощью инструмента? Потому что силой мысли в малоизвестном проекте размером в 10 Мбайт найти "узкие места" не удастся\. Затем эти узкие места программист делает параллельными с помощью OpenMP\. После этого, можно искать следующие узкие места и так далее, до тех пор, пока не будет получена желаемая производительность приложения\. Процесс разработки параллельной версии можно прерывать, выпускать промежуточные релизы, возвращаться к нему по мере необходимости\. Именно поэтому в частности технология OpenMP стала довольно популярной\.

## Что же такое OpenMP?

OpenMP \(Open Multi\-Processing\) \- это набор директив компилятора, библиотечных процедур и переменных окружения, которые предназначены для программирования многопоточных приложений на многопроцессорных системах с общей памятью \(SMP\-системах\)\.

Первый стандарт OpenMP был разработан в 1997 г\. как API, ориентированный на написание легко переносимых многопоточных приложений\. Сначала он был основан на языке Fortran, но позднее включил в себя и языки Си и Си\+\+\.

Интерфейс OpenMP стал одной из наиболее популярных технологий параллельного программирования\. OpenMP успешно используется как при программировании суперкомпьютерных систем с большим количеством процессоров, так и в настольных пользовательских системах или, например, в Xbox 360\.

Разработку спецификации OpenMP ведут несколько крупных производителей вычислительной техники и программного обеспечения, чья работа регулируется некоммерческой организацией "OpenMP Architecture Review Board"\.

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

Число потоков в группе, выполняющихся параллельно, можно контролировать несколькими способами\. Один из них \- использование переменной окружения OMP\_NUM\_THREADS\. Другой способ \- вызов процедуры omp\_set\_num\_threads\(\)\. Еще один способ \- использование выражения num\_threads в сочетании с директивой parallel\.

## Анонс ближайших заметок по параллельному программированию

Этой записью мы начинаем небольшой цикл публикаций посвященных знакомству с технологией OpenMP и инструментарием для разработки параллельных приложений\. В следующих заметках вы узнаете:

* какие инструменты нужны для разработки параллельных программ;
* как создать с нуля параллельную программу;
* как добавить в существующую программу параллельное выполнение с помощью технологии OpenMP;
* какие типовые проблемы возникают при разработке OpenMP \-приложений и как их диагностировать;
* оптимизация параллельных программ\.

Ждите следующего выпуска уроков\.

## Дополнительные материалы

1. [Сообщество "Параллельное программирование" на сайте Intel Software Network](https://software.intel.com/content/www/ru/ru/develop/topics/modern-code.html)\.
1. Статья "[Технология OpenMP](https://pvs-studio.ru/ru/blog/posts/a0057/)"\.