330 likes | 512 Views
Основы разработки высокопроизводительных параллельных приложений. Практикум. Департамент стратегических технологий, Microsoft. Содержание. Инфраструктура. Туалеты Перерывы Эвакуация != Тренеры Денис Котляров, Microsoft Василий Маланин , Microsoft
E N D
Основы разработки высокопроизводительных параллельных приложений. • Практикум. Департамент стратегических технологий, Microsoft.
Инфраструктура • Туалеты • Перерывы • Эвакуация != Тренеры Денис Котляров, Microsoft Василий Маланин, Microsoft Андрей Паринов, Независимый эксперт Группа поддержки
Часть 1. Введение в параллелизм. Многопоточное программирование.
Введение • Зачем? • Типы параллелизма. • Ускорение->ЭффективностьvsПереносимость • Распараллеливание = Инструменты && • (Предметные области || Задачи)
Описание предметной области 800 600
n = количество проц. Tпаралл.= {(1-P) + P/n}Tпослед P Ускорение= Tпослед/ Tпаралл. P/2 Послед. T P/∞ (1-P) (1-P) Закон Амдала • Описывает верхний предел ускорения от параллельного выполнения Последовательный код ограничивает ускорение
Постановка задач для кластера в HPCS Адрес MSU кластера \ IKI кластера HN.PRACTICUM.CS.MSU.SU \ 193.232.2.150 Имя головного узла (head node)hn.practicum\hn.cluster.local Имя вычислительных узлов cn1,cn2…\ cn1.cluster.local,cn2.cluster.local… Сетевая папка доступная всем hn.practicum\apps \ hn.cluster.local\apps вычислительным узлам Сетевая папка на каждом \\cn1\Apps, \\cn2\Apps... \ cn1.cluster.local\apps вычилительном узле (физический расположенная в C:\Apps) Для доступа к IKI кластеру необходимо включить VPN соединение, указав User name: <user_ name> Password: < password> Domain: Cluster
Последовательно о многопоточном.
Stack Сегмент кода Сегмент данных Stack Stack thread thread … Процессы и потоки Преимущества потоков: • Быстрое переключение между потоками (переключение между процессами очень ресурсоемкая операция) • Простая организация взаимодействия – общая память Недостатки потоков: • Некорректное использование данных одним потоком отражается на всех других • Необходимость в синхронизации при доступе к общим данным • Используемые библиотеки должны поддерживать многопоточность thread main()
Средства создания многопоточных программ • Ручные: Библиотеки потоков • Posix Threads • Windows Threads • … • Полуавтоматические: OpenMP • Автоматические: Распараллеливающие компиляторы • Неявный параллелизм (F#)
Синхронизация потоков Необходима при: • Совместном использовании ресурса (атомарные операции) • Уведомлении потоков о некотором событии
n = количество проц. Tпаралл.= {(1-P) + P/n}Tпослед P Ускорение= Tпослед/ Tпаралл. P/2 Послед. T P/∞ (1-P) (1-P) Закон Амдала • Описывает верхний предел ускорения от параллельного выполнения Последовательный код ограничивает ускорение
Главный поток Параллельные регионы Просто OpenMP Параллелизм Fork-join: • Главный поток (Master thread) порождает группу потоков по необходимости • Параллелизм добавляется постепенно • Последовательная программа “трансформируется в параллельную”
Параллельные циклы • Определите циклы на вычисление которых уходит наибольшее количество времени. • Распределите их о выполнение между потоками. Распределить цикл между потоками #include “omp.h”void main(){ double Res[1000];#pragmaomp parallel forfor(inti=0;i<1000;i++){ do_huge_comp(Res[i]); }} void main(){ double Res[1000]; for(inti=0;i<1000;i++){ do_huge_comp(Res[i]); }} Последовательная программа Параллельная программа
Просто OpenMP • Примитивы OpenMPподразделяются на категории: • Функции времени выполнения/переменные среды окружения • Параллельные регионы • Распределение работ • Синхронизация • Принципиально OpenMPне зависит от компилятора или языка, например Fortran и C/C++
Функции • Примитивы среды окружения: • Изменить/проверить количество потоков • omp_set_num_threads() • omp_get_num_threads() • omp_get_thread_num() • omp_get_max_threads() • Мы в параллельном регионе? • omp_in_parallel() • Сколько процессоров в системе? • omp_num_procs()
Функции • Чтобы установить количество потоков Установить количество потоков равное количеству процессоров #include <omp.h>void main(){ intnum_threads;omp_set_num_threads(omp_num_procs());#pragmaomp parallel { int id=omp_get_thread_num();#pragmaomp single num_threads = omp_get_num_threads(); do_lots_of_stuff(id); }} Глоб. Переменная. Операция выполняется в одном потоке.
Переменные среды коружения • Установить количество потоков, порождаемых по умолчанию • OMP_NUM_THREADS int_literal • Установить способ распределения нагрузки по умолчанию • OMP_SCHEDULE “schedule[, chunk_size]”
Правила разделения переменных • Неявное правило 1: Все переменные, определенныевнеomp parallel,являются глобальнымидля всех потоков • Неявное правило 2:Все переменные, определенныевнутриomp parallel,являются локальнымидля каждого потока • Неявное исключение:В прагмеomp for, счетчик циклавсегдалокалендля каждого потока • Явное правило 1: Переменные, приведенные вshared(),являются глобальнымидля всех потоков • Явное правило 2:Переменные, приведенные вprivate(),являются локальнымидля каждого потока
Какие переменные локальные, а какие глобальные? • void func() • { • int a, i; • #pragmaomp parallel for \ • shared(c) private(d, e) • for (i = 0; i < N; i++) • { • int b, c, d, e; • a = a + b; • c = c + d * e; • } • }
Прагмы синхронизации • #pragmaompsingle – исполняет следующую команду толькос помощью одного (случайного) потока • #pragmaompbarrier – удерживает потоки в этом месте, пока все потоки не дойдут дотуда • #pragmaompatomic– атомарно исполняет следующую операцию доступа к памяти (т.е. без прерывания от других ветвей) • #pragmaompcritical [имя потока] – позволяет только одному потоку перейти к исполнению следующей команды • int a[N], sum = 0; • #pragmaomp parallel for • for (inti = 0; i < N; i++) • { • #pragmaomp critical • sum += a[i]; // one thread at a time • }
Реализация параллельного алгоритма с использованием OpenMP Применяется OpenMP с помощью указания директив. Например : #pragmaomp parallel for for (inti = 0; i < N; i++) PerformSomeComputation(i);
Реализация параллельного алгоритма с использованием OpenMP Важно помнить про ситуацию (race conditions), которая возникает при одновременном доступе к общим переменным. #pragmaomp parallel for schedule(static) for (inti = 0; i < N; i++) PerformSomeComputation(i); Пусть функция PerformSomeComputation изменяет значение глобальной переменной int global = 0; void PerformSomeComputation(inti) { global += i; } .
Реализация параллельного алгоритма с использованием OpenMP Избежать ситуацию возникновения гонки за ресурсами. Позволяет использование критических секций: void PerformSomeComputation(inti) { #pragmaomp critical { global += i; } }
Выполнение упражнения #pragmaomp parallel for schedule(static) reduction(+:diffs) for (int row = 1; row < rows-1; row++)