
Лекции / Лекция 1
.odtТехнологии и методы программирования. Лекция 1.
Параллельное программирование и распределённые вычисления.
В данном курсе будет рассматриваться параллельное программирование на примере технологии openmp.
Openmp.org – ресурс об openmp. В данный момент поддерживаются версии 2.0, 2.5.
Компилятор, позволяющий работать с openmp – VS-2008+.
Языки, поддерживающие openmp – C/C++, Fortran.
Основные компоненты технологии openmp:
1) Основные директивы транслятору
В С директивы имеют вид прагм: #pragma omp parallel {этот оператор будет выполняться в каждом из потоков}
2) Библиотечные функции
Библиотечные функции обеспечивают управление параллельными потоками.
3) Переменные среды окружения.
Переменные среды также участвуют в управлении потоками, возможно управление без повторной компиляции.
Модель выполнения программ:
Количество потоков в параллельном участке определяется или по умолчанию, или в результате управления потоками. По его окончании происходит барьерная синхронизация — завершение всего параллельного участка при завершении самого медленного потока. Остальные потоки останавливаются, ожидая завершения последнего. В openmp возможно использование вложенных параллельных участков (только в специальном режиме).
Модель памяти:
В openmn переменные бывают общие и индивидуальные. Индивидуальные принадлежат некоторому потоку и только этот поток может читать и записывать их значения (в момент распараллеливания индивидуальные переменные многократно копируются и каждый поток работает со своей, независимой от других, переменной). Общие переменные доступны всем потокам из одной группы. Если чтение/запись в них происходит без синхронизации, то результирующее значение не определено.
Пример:
#include <stdir.h>
#include <omp.h>
int main (){
#pragma omp patallel
printf(“Работает поток”);
}
Сообщение будет выведено столько раз, сколько было запущено потоков, по умолчанию — 2 раза.
Структура директивы:
#pragma – обозначение директивы
omp – то, что запускается
parallel – опция
Управление количеством потоков:
- через переменную среды OMP_NUM_THREADS
- через опции директивы: #pragma omp parallel num_threads(переменная числа потоков, к примеру, int n=4)
Практически число потоков не должно быть больше, чем число процессоров/ядер. Узнать это число можно функцией int omp_get_num_proc(), возвращающей число доступных процессоров. Количество потоков в группе определяется функцией int omp_get_num_threads(), номер текущего потока — int omp_get_thread_num().
Опции переменных(управление видом переменных).
Вид переменных определяется по умолчанию или явно. По умолчанию любая переменная, объявленная вне блока параллельных вычислений — общая. Статические переменные — всегда общие. Переменные, объявленные внутри блока параллельных вычислений — индивидуальные, локальные переменные и формальные параметры функций, вызываемых внутри блока параллельных вычислений — всегда индивидуальные. Эти правила можно изменять опциями директивы parallel:
- private(индивидуальные переменные) – не выполняется автоматическая инициализация, при выходе из параллельного участка значение этих переменных не определено.
- first_private(индивидуальные переменные) – то же самое, но переменные инициализируются значением переменной из главного потока.
- redaction(оператор, индивидуальные переменные) – значение переменной после выхода из параллельного участка определяется применением оператора к индивидуальным переменным из списка.
Пример:
a=x;
#pragma omp parallel redaction(+, a)
{
здесь индивидуальные переменные принимают значения x1, x2, … xn
}
после выполнения параллельного участка а=x1+x2+...+xn.