Лекция №5 (lec_paral_5)

advertisement
Материал к лекции №5.
Часть материала данной лекции соответствует
1. © Лаборатория Параллельных Информационных Технологий, НИВЦ МГУ
http://parallel.ru/tech/tech_dev/openmp.html
2. В.П. Гергель, Р.Г. Стронгин
Основы
многопроцессорных вычислительных систем
параллельных
вычислений
для
3. Материалы тренингов Intel, проведенного в апреле 2006 года для преподавателей ВУЗов
4. Джин Бэкон, Тим Харрис Операционные системы. Параллельные и распределенные
системы. – bhv «Питер» - 2004 – 799 с.
5. Э.В. Прозорова «Вычислительные методы механики сплошной среды» СпбГУ, 1999
ВВЕДЕНИЕ ...................................................................................................................................1
ВВЕДЕНИЕ В OPENMP .............................................................................................................2
ФУНКЦИОНАЛЬНЫЙ ПАРАЛЛЕЛЕЛИЗМ И ПАРАЛЛЕЛЕЛИЗМ ПО ДАННЫМ ....................................5
Декомпозиция по данным ......................................................................................................5
МЕТОД «УСПЕШНОГО ПРОГРАММИРОВАНИЯ» В OPENMP ...................................5
ГЛАВНОЕ – ПРАВИЛЬНО ВЫБРАТЬ ОБЪЕКТ : ЗАДАЧУ И АЛГОРИТМ ..............................................6
ВЫБОР СТРУКТУР ПРЕДСТАВЛЕНИЯ ДАННЫХ – УСЛОВИЕ УСПЕХА №2 .......................................6
ВЫБОР ПАРАЛЛЕЛЬНОЙ СХЕМЫ – УСЛОВИЕ №3 .........................................................................7
ВЫБОР КЛЮЧЕЙ КОМПИЛЯЦИИ – УСЛОВИЕ №4 ..........................................................................8
ОЦЕНКА ВРЕМЕННЫХ ЗАТРАТ ПРИ СОЗДАНИИ ПАРАЛЛЕЛЬНОГО ПРИЛОЖЕНИЯ В OPENMP .......8
ПРОГРАММИРОВАНИЕ В OPENMP
ВВЕДЕНИЕ
Справочный материал по OpenMP на русском языке, необходимый для первого
знакомства, подготовлен Лабораторией Параллельных Информационных Технологий,
НИВЦ МГУ и находится на http://parallel.ru/tech/tech_dev/openmp.html
Перед тем, как начать изучение материала данной лекции, рекомендуется
просмотреть материал на ссылке. Этот же материал содержится в файле, лежащем в
данной папке в файле OpenMP_parallel_ru.doc, и частично дублируется в материале
лекции.
В данной лекции в основном рассматриваются принципы, следование которым
должно обеспечить создание эффективно работающей программы в OpenMP, а также
демонстрационные примеры.
Кроме того, в лекции содержатся справочные сведения по наиболее популярным
конструкциям OpenMP.
1
ВВЕДЕНИЕ В OPENMP
[1]
«Интерфейс OpenMP задуман как стандарт для программирования на
масштабируемых SMP-системах (SSMP,ccNUMA, etc.) в модели общей памяти (shared
memory model).»( http://parallel.ru/computers/classes.html - классификация систем с общей
памятью)
OpenMP можно рассматривать как высокоуровневую надстройку над
библиотеками потоков (нитей), которые полностью находятся в ведении операционной
системы. Это хорошо иллюстрирует слайд из учебника на www.openmp.org :
Рис. 1. Архитектура OpenMP.
Для одновременного выполнения программы на нескольких процессорах, нужно,
чтобы было возможно выполнение потоков на разных процессорах (ядрах). В
современных Windows для этого невозможно обойтись без класса «облегченные потоки»
(рис. 2), которые регистрируются как потоки ядра. Выполнение «облегченных потоков»
планируется непосредственно ядром операционной системы на основе единой стратегии;
любой из них может независимо выполняться на отдельном процессоре (ядре).
Приложение на основе пользовательских потоков («нитей») может эффективно
использовать возможности мультипроцессора только в том случае, если в нем
задействовано более одного облегченного потока и реализован механизм управления
параллельным выполнением, обеспечивающий взаимодействие нитей разных потоков [4].
Основным недостатком потоков ядра являются ресурсные затраты на
переключение контекста: все переключения выполняются через ядро и обычно занимает в
10 раз больше времени, чем переключение пользовательских потоков.
В Unix планировщик, как и большинство других компонентов ядра, выполняется в
контексте пользовательского процесса.
2
Заметим, что
для других операционных систем минимальное количество
«облегченных» потоков, необходимое для эффективной работы мультипроцессора, может
быть совершенно другим.
Например, в SunOS реализована схема комбинированного управления потоками:
наряду с пользовательскими потоками (рис. 1.), жестко соответствующими определенным
потокам ядра, используются пользовательские потоки, которые могут выполняться в
любом из нескольких потоков ядра. А ресурсные затраты на переключение контекста
между пользовательскими потоками намного меньше! Такой подход обеспечивает и
гибкость разработки приложений, и их высокую производительность. Потоки ядра при
этом называются легковесными процессами, а пользовательские потоки – просто
потоками.
Ниже приводится иллюстрация классов потоков.
Рис. 2. Классы потоков. В Windows для реализации эффективной работы
мультипроцессора необходимо создание «облегченных» потоков по количеству
процессоров.
Таким образом, в зависимости от особенностей потоков выбранной операционной
системы, «накладные расходы» (parallel overhead) на реализацию различных конструкций
OpenMP будут отличаться для различных операционных систем.
Потоки совместно используют адресное пространство приложения и все
выделенные ему операционной системой ресурсы, такие как память и открытые файлы,
отличаясь только состоянием стека ([3]):
3
Рис. 3. Отношения между процессом (вся закрашенная область) и входящими в
него потоками.
[1]
«В стандарт OpenMP входят спецификации набора директив компилятора,
процедур и переменных среды…. В OpenMP используется терминология и модель
программирования, близкая к Pthreads (динамически порождаемые нити, общие и
разделяемые данные, механизм "замков" для синхронизации).»
[2]
«В рамках данной технологии директивы параллелизма используются для
выделения в программе параллельных областей (parallel regions), в которых
последовательный исполняемый код может быть разделен на несколько раздельных
командных потоков (threads). Далее эти потоки могут исполняться на разных процессорах
вычислительной системы. В результате такого подхода программа представляется в виде
набора последовательных (однопотоковых) и параллельных (многопотоковых) участков
программного кода... Подобный принцип организации параллелизма получил
наименование "вилочного" (fork-join) или пульсирующего параллелизма.»
При выполнении OpenMP программы главный поток (мастер – поток, или поток с
нулевым номером) создает по мере необходимости дополнительные потоки (см. рис. 4).
Рис. 4. Модель параллельного программирования в OpenMP.
Большинство
(pragmas).
конструкций
OpenMP*
4
являются
директивами
компилятора
Но OpenMP обладает не только возможностями по распараллеливанию простых
циклов.
[1]
«Одним из достоинств OpenMP его разработчики считают поддержку так
называемых "orphan" (оторванных) директив, то есть директивы синхронизации и
распределения работы могут не входить непосредственно в лексический контекст
параллельной области.»
Главное предназначение OpenMP – максимально быстрое преобразование
последовательной программы в параллельную и переносимость OpenMP – программы на
различные платформы.
[1]
«Предполагается, что OpenMP-программа на однопроцессорной платформе может
быть использована в качестве последовательной программы, т.е. нет необходимости
поддерживать последовательную и параллельную версии. Директивы OpenMP просто
игнорируются последовательным компилятором, а для вызова процедур OpenMP могут
быть подставлены заглушки (stubs), текст которых приведен в спецификациях.»
[1]
«Основной источник информации об OpenMP - сервер www.openmp.org. На
сервере доступны спецификации, статьи, учебные материалы, ссылки…»
OpenMP поддерживает параллелелизм по данным, наиболее эффективен именно
для него, хотя функциональный параллелелизм также может быть реализован средствами
OpenMP.
Функциональный параллелелизм и параллелелизм по
данным
Функциональная декомпозиция сфокусирована на методах обработки данных,
выявляя структуру задачи.
Декомпозиция по данным сфокусирована на выявлении типов структур данных.
Параллелелизм по данным: одинаковые операции – к разным данным.
Функциональная декомпозиция
Задача потока связана со «стадией вычислений»
• Аналогия с конвейером сборки автомобиля – каждый рабочий(поток) параллельно с
другими собирает все детали одного (своего) типа – затем общая сборка автомобиля.
Декомпозиция по данным
• Потоковый процесс выполняет все стадии для своего блока данных
• Каждый рабочий собирает свой автомобиль.
МЕТОД «УСПЕШНОГО ПРОГРАММИРОВАНИЯ» В OPENMP
5
Главное – правильно выбрать объект : задачу и алгоритм
Как известно, любая программная реализация задачи зависит от алгоритма,
выбранного для ее решения, структур для представления данных этой задачи и, наконец,
методов программирования в рамках выбранных системы и технологии
программирования на базе архитектурной и операционной платформы.
Именно задача является определяющим фактором для выбора всего остального. Но
поскольку в рамках данного спецкурса мы ограничиваемся методологией императивного
параллельного программирования в системах с общей памятью, мы неизбежно должны
сузить класс задач и алгоритмов, укладывающихся в рамки данного подхода.
Отметим, что OpenMP наиболее оптимально применять для реализации явных
параллельных конструкций, по крайней мере, для выбранных нами операционной и
архитектурной платформ.
Причина этого была уже установлена нами экспериментально на предыдущих
занятиях: затраты на переключение контекста между потоками достаточно велики –
порядка 200 циклов процессора.
Таким образом, OpenMP подходит для класса задач, в алгоритмах решения которых
допустим явный параллелелизм, либо используются «наиболее дешевые» операции
синхронизации (например, изменение переменной в результате простой операции), либо
необходимость в синхронизации возникает очень редко.
В данном спецкурсе предполагается рассмотреть алгоритмы, используемым в
численных методах механики сплошных сред.
[5]
«Оптимальное использование возможностей машины достигается в этом случае
при алгоритмах, организованных в виде независимых блоков. С этой точки зрения
эффективность работы машины зависит от организации решения системы линейных
алгебраических уравнений, к которой сводится в конечном счете решение задачи.
Наиболее популярной разностной схемой в настоящее время является схема
расщепления (факторизации), т.е. представления задачи в виде набора более простых
задач. Способы расщепления разнообразны. Операторы, входящие в каждый блок
(простую задачу), могут содержать первые производные по одному из направлений,
включать в себя производные по времени или отдельные физико-химические процессы.»
Применение OpenMP будет особенно эффективно для класса явных схем, например
схем TVD.
Отметим также, что эффективно может быть распараллелен метод конечных
элементов.
Выбор структур представления данных – условие успеха №2
Тем не менее, и программная реализация алгоритма допускает большие вариации.
Одним из определяющих факторов программной реализации алгоритма является выбор
структур представления данных задачи. Этот выбор диктуется не только задачей, но и
6
возможностями системы программирования. А в выборе оптимальных структур данных
необходимо учитывать свойства операционной и архитектурной платформ.
Отметим здесь лишь наиболее важные требования, которым должны удовлетворять
структуры данных (при условии удовлетворения условиям задачи).
С одной стороны, нужно учитывать, что подгрузка данных в кэш осуществляется
согласно принципу «локальной близости» и «повторной используемости» данных. С этой
точки зрения данные «часто» и «вместе» используемые должны быть расположены рядом.
Кроме того, необходимо оценить отношение реальных объемов информации для
разных структур данных в строках кэша, которые будут передаваться по «общим
коммуникациям» при работе параллельной программы.
Пусть, например, решается следующая задача: на основе элементов двух массивов
определяются значения элементов третьего массива: c[I] = fun(a[I], b[I]).
В этом случае при программировании на «CИ» будет оптимальнее использовать не
структуру массивов Massiv.a[I], Massiv.b[I], Massiv.c[I], а массив структур Massiv[I].a,
Massiv[I].b, Massiv[I].c.
Во-первых, элементы массивов располагаются в памяти не рядом – значит, на
доступ к объектам, расположенным в разных областях, потребуются дополнительные
затраты. А три элемента структуры лежат рядом! Однако и объем передаваемых данных
будет отличаться: за счет того, что размещение элементов массивов «не выровнено в
памяти», в обмене реально будет участвовать больший объем информации, чем в случае
использования структуры массивов.
В некоторых случаях оптимальный выбор структур представления данных можно
осуществить на уровне последовательного кода, а в некоторых случаях – только на уровне
параллельной программы.
Заметим, что если преобразование структур данных в оптимальную форму перед
началом вычислений бывает выгодно даже в том случае, если, казалось бы, в ходе
вычислений понадобится то же количество операций, что и при преобразовании
(например, транспонирование матрицы перед умножением матриц).
Выбор параллельной схемы – условие №3
Выбор параллельной схемы во многом уже был предопределен выбором алгоритма
решения задачи и структур представления данных. Но все равно остаются альтернативные
варианты: как распределить задания между потоками, какие механизмы синхронизации
применить, какие конструкции OpenMP выбрать.
В этом случае необходимо соблюдать следующие требования

Объем информации, передаваемой по «общим коммуникациям», минимален
7

Отличия во временных затратах потоков на выполнение заданий к моменту их
синхронизации минимальны – потоки «не ждут друг друга», минимальный
дисбаланс

Конструкции OpenMP с минимальными «накладными расходами»
Нужно отметить, что технология OpenMP может быть «дружественна» с режимом
компиляции, а может быть и нет. Одни программы могут быть ускорены и за счет
применения ключей компиляции, и за счет распараллеливания, в то время как другие уже
никак не оптимизируются после применения OpenMP.
Общая рекомендация такова: отдавать предпочтение параллельным схемам, где в
заданиях для потоков «не возникают новые зависимости по данным».
Например, в параллельной схеме «обработка элементов массива через один»
компилятор может «видеть зависимость по данным», в результате чего параллельная
схема будет медленнее последовательной, но оптимизированной компилятором.
Выбор ключей компиляции – условие №4
Оптимизация с помощью режимов компиляции – мощное средство. Например,
процесс умножение матриц может быть ускорен в 98 раз на двухъядерной архитектуре: в
два раза за счет распараллеливания, в два раза – за счет улучшения работы с памятью
методом выбора структур данных (транспонирование второй матрицы перед умножением)
и их обработки – и более, чем в 20 раз – за счет выбора ключей компиляции.
Фрагмент кода программы умножения матриц 1024 X 1024 (автор О. Нечаева).
#pragma omp parallel for private(j,k)
for(int i=0;i<Size;i+=4)
for(int j=0;j<128;j++)
{
for(int k=0;k<Size;k++)
{
C[i][j]+=A[i][k]*B[j][k];
C[i+1][j]+=A[i+1][k]*B[j][k];
C[i+2][j]+=A[i+2][k]*B[j][k];
C[i+3][j]+=A[i+3][k]*B[j][k];
}
}
Оценка временных затрат при создании параллельного
приложения в OpenMP
Как правило, хорошая программа в OpenMP имеет вид последовательного кода с
одинокими (одной - двумя) конструкциями OpenMP. Ниже приводится фрагмент кода
программы, осуществляющей преобразование Фурье. При этом в функции, к которой
осуществляется обращение, параллельных конструкций нет
start = rdtsc(); //start time
for( i = 0 ; i < power ; i++ )//steps
8
{
#pragma omp parallel for private (index)
for( j = 0 ; j < num_points ; j++)
{
index = j << (i + 1);
fft_index(offset, num_points, index, arg,
arg_2, f_Re, f_Im);
}
num_points >>= 1;
offset <<= 1;
}//end of fft algorithm
stop = rdtsc()-start;
Но какие же усилия за этим стоят? Если оценить временные затраты при условии, что
разработчик хорошо знаком со свойствами конструкций OpenMP, то результат выглядит
примерно следующим образом:




Выбор алгоритма – 40% времени
Выбор структур представления данных – 40%
Выбор параллельной схемы - 15%
Выбор режима компиляции – 5%
Заметим, что процесс выбора алгоритма, структур данных, параллельной схемы и
режима компиляции может быть итеративный и круговой.
9
Download