Санкт-Петербургский государственный университет
Опубликован: 11.10.2012 | Доступ: свободный | Студентов: 955 / 173 | Длительность: 05:14:00
Лекция 8:

Программирование с использованием OpenMP

< Лекция 7 || Лекция 8: 123 || Лекция 9 >
Аннотация: В современных высокопроизводительных системах объединяются архитектура с распределённой памятью и архитектура с общей памятью (на уровне отдельного вычислительного узла). Использование OpenMP позволяет эффективно использовать возможности таких систем. В восьмой лекции рассматриваются особенности модели программирования, основанной на параллелизме потоков. Даётся обзор OpenMP.

Презентацию к данной лекции Вы можете скачать здесь.

Многопоточная модель параллельного программирования

Поток (нить) представляет собой последовательный поток управления (последовательность команд) в рамках одной программы.

При создании процесса порождается главный поток, выполняющий инициализацию процесса. Он же начинает выполнение команд.

Поток и процесс соотносятся следующим образом:

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

Конкуренция за ресурсы и параллельное исполнение

Конкуренция за ресурсы (видимый параллелизм)


Реальный параллелизм


Для реализации реального параллелизма требуется соответствующая архитектура – многоядерная или многопроцессорная с общей памятью.

При разработке многопоточных приложений возникают следующие проблемы:

  • гонки за данными;
  • блокировки;
  • несбалансированность загрузки.
Гонки за данными (data races)

Гонки за данными являются следствием зависимостей, когда несколько потоков модифицируют содержимое одной и той же области памяти. Наличие гонок за данными не всегда является очевидным. Они могут приводить к конфликтам двух типов:

  1. конфликт "чтение-запись";
  2. конфликт "запись-запись".
Два способа борьбы с гонками за данными:
  • использование преимущественно локальных по отношению к потоку, а не разделяемых переменных;
  • управление доступом к разделяемым переменным с помощью различных средств синхронизации (они могут быть реализованы с помощью семафоров, событий, критических секций, взаимных блокировок - мьютексов).
Блокировки

Блокировка (тупик) возникает, если поток ожидает выполнение условия, которое не может быть выполнено. Обычно возникновение тупиковой ситуации является следствием конкуренции потоков за ресурс, который удерживается одним из них.

Условия возникновения тупика
  • доступ к ресурсу эксклюзивен (возможен только одним потоком);
  • поток может удерживать ресурс, запрашивая другой;
  • ни один из конкурирующих потоков не может освободить запрашиваемый ресурс.
Масштабируемость

Число программных потоков должно совпадать с числом аппаратных потоков


Реализации
POSIX Threads Windows API низкоуровневые инструменты
OpenMP высокоуровневые инструменты

OpenMP. Модель программы и структура


  • Программа состоит из последовательных и параллельных секций.
  • В начальный момент времени создается главная (мастер) нить, выполняющая последовательные секции программы.
  • При входе в параллельную секцию выполняется операция fork, порождающая семейство нитей. Каждая нить имеет свой уникальный числовой идентификатор (главной нити соответствует 0). Все параллельные нити исполняют один код.
  • При выходе из параллельной секции выполняется операция join. Завершается выполнение всех нитей, кроме главной.
  1. Директивы компилятора - используются для создания потоков, распределения работы между потоками и их синхронизации. Директивы включаются в исходный текст программы.
  2. Подпрограммы библиотеки времени выполнения - используются для установки и определения атрибутов потоков. Вызовы этих подпрограмм включаются в исходный текст программы.
  3. Переменные окружения- используются для управления поведением параллельной программы.

Привязки к языкам

Привязка к языку C

Прагмы, имена функций и переменных окружения OpenMP начинаются с omp, omp_ или OMP_

Формат директивы: #pragma omp директива [оператор_1[, оператор_2, …]]

Заголовочный файл omp.h.

Привязка к языку Fortran

Директивы компилятора, имена подпрограмм и переменных окружения начинаются с OMP или OMP_.

Формат директивы компилятора:

{!|C|*}$OMP директива [оператор_1[, оператор_2, …]]

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

< Лекция 7 || Лекция 8: 123 || Лекция 9 >