1 Оптимизация ПО для поддержки технологии Hyper-Threading с помощью OpenMP и Intel ® Threading Toolkit Максим Перминов Разработчик ПО, корпорация Intel
2 Содержание Технология Hyper-Threading – многопоточность – OpenMP Наша первая программа на OpenMP Наша первая корректная программа на OpenMP Оптимизация производительности с помощью Intel ® Threading Toolkit
3 Как работает технология HT Физические процессоры Логические процессоры видимые для ОС Физический процессор распределение ресурсов На выходе Время Ресурс 1 Ресурс 2 Ресурс 3 Поток 2 Поток 1 Без Hyper- Threading С Hyper- Threading Поток 2 Поток 1 Ресурс 1 Ресурс 2 Ресурс 3 + Лучшее использование ресурсов и более высокая производительность благодаря двум одновременно обрабатываемым потокам
4 Что? Стратегия многопоточности –Распараллеливание задачи –Распараллеливание данных Как? Внедрение многопоточности –Языки программирования (C#, Java) –API / Библиотека (Win32, P-потоки, MPI) –Расширение языков программирования (OpenMP) Разбивайте Ваше приложение на несколько потоков OpenMP позволяет ускорить распараллеливание задач и данных
5 Что такое OpenMP ? Расширение компилятора для легкого распараллеливания НЕ МЕНЯЕТ КОД C/C++ Три компоненты: –#pragma (директива компилятора) – самое важное –API и библиотека Runtime –Переменные окружения Преимущества: –Легкий путь использования Hyper-Threading –Переносимость и стандартизация –Постепенное распараллеливание –Специальные инструменты профилирования
6 Модель программирования Параллельность типа «разветвление- соединение»: –основной поток порождает группу дополнительных потоков –Группа потоков соединяется в конце области распараллеливания Вся память (переменные) совместно используется по умолчанию Распараллеливание можно осуществлять шаг за шагом –Последовательная программа разворачивается в параллельную Области распараллеливания группа потоков основной поток
7 Наша первая программа на OpenMP Все прагмы OpenMP начинаются с omp Прагма parallel порождает группу из n потоков Все внутри исполняется n раз! Вся память используется совместно! void func() { int a, b, c, d; a = a + b; c = c + d; } void func() { int a, b, c, d; #pragma omp parallel { a = a + b; c = c + d; }
8 Упражнение 1: Hello OpenMP Изначальный код –Откройте проект PrimeHT.dsp –Скомпилируйте и запустите, используя стандартный компилятор Microsoft* –Скомпилируйте и запустите, используя компилятор Intel ® Compiler; отметьте результаты Hello OpenMP –Найдите в PrimeHT.cpp цикл, серьезно влияющий на производительность –Создайте вокруг него область распараллеливания OpenMP Оставьте код тайминга вне области распараллеливания –Включите в Intel Compiler поддержку OpenMP опция /Qopenmp –Скомпилируйте и запустите –Можете объяснить результаты?
9 Приписывание задач потокам Разделяющие работу прагмы приписывают задачи потокам Прагма sections приписывает неитеративные задачи void func() { int a, b, c, d; #pragma omp parallel { #pragma omp sections { #pragma omp section a = a + b; //one thread #pragma omp section c = c + d; //another thread }
10 Прагмы, разделяющие задачу Прагмы, разделяющие задачу, можно объединять с прагмой parallel void func() { int a, b, c, d; #pragma omp parallel sections { #pragma omp section a = a + b; //one thread #pragma omp section c = c + d; //another thread } #pragma omp parallel sections { #pragma omp section do_compress(); #pragma omp section do_encrypt(); } Две функции, исполняющиеся параллельно: #pragma omp parallel sections Распараллеливание на уровне задания!
11 Упражнение 2: Parallel Sections Разбейте основной цикл на два например, from.. to/2 и to/2.. to Превратите общую область в конструкцию «parallel sections» Поместите каждый подцикл в свою секцию Скомпилируйте и запустите; (попытайтесь) объяснить результат
12 Разделение работы на циклах Прагма for приписывает циклы потокам Есть несколько способов сделать это… Между прочим, что делается в приведенном примере? void func() { int a[N], sum = 0; #pragma omp parallel for for (int i = 0; i < N; i++) { sum += a[i]; } #pragma omp parallel for Распараллеливание на уровне данных!
13 Упражнение 3: Parallel For Восстановите один основной цикл from.. to Превратите общую область в конструкцию «parallel for» Скомпилируйте и запустите Объясните результат
14 Правила разделения переменных Неявное правило 1: Все переменные, определенные вне omp parallel, являются глобальными для всех потоков Неявное правило 2: Все переменные, определенные внутри omp parallel, являются локальными для каждого потока Неявное исключение : В прагме omp for, счетчик цикла всегда локален для каждого потока Явное правило 1: Переменные, приведенные в shared(), являются глобальными для всех потоков Явное правило 2: Переменные, приведенные в private(), являются локальными для каждого потока
15 Какие переменные локальные, а какие глобальные? void func() { int a, i; #pragma omp 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; }
16 Упражнение 4: области действия переменных С помощью указанных выше правил установите области действия переменных в основном цикле Скомпилируйте и запустите Объясните результат
17 Проблема синхронизации sum++; mov eax, [sum] add eax, 1 mov [sum], eax mov eax, [sum] add eax, 1 mov [sum], eax s s+1 s s s ветвь 1 исполняет ветвь 1 eax ветвь 2 eax s сумма t+0 t+1 t+2 такт s+1 Код C Команды процессора mov [sum], eax s+1 t+3 Не то, что мы ожидали!
18 Прагмы синхронизации #pragma omp single – исполняет следующую команду только с помощью одного (случайного) потока #pragma omp barrier – удерживает потоки в этом месте, пока все потоки не дойдут дотуда #pragma omp atomic – атомарно исполняет следующую операцию доступа к памяти (т.е. без прерывания от других ветвей) #pragma omp critical [ имя потока ] – позволяет только одному потоку перейти к исполнению следующей команды int a[N], sum = 0; #pragma omp parallel for for (int i = 0; i < N; i++) { #pragma omp critical sum += a[i]; // one thread at a time }
19 Упражнение 5: синхронизация Для решения нашей проблемы синхронизации используйте нужную прагму синхронизации Скомпилируйте и запустите
20 Упражнение 6: профилирование Включите в компиляторе профилирование OpenMP /Qopenmp_profile Скомпилируйте снова Создайте проект Intel ® Thread Profiler для PrimeHT.exe ; примите все настройки по умолчанию Запустите Intel ® VTune Performance Analyzer New Project | Threading Toolkit | Thread Analyzer Wizard; проверьте: Number of Threads = 2 Запустите сессию профилирования Посмотрите результат в видах Summary, Threads, Regions
21 omp for schedule : схемы schedule определяет, как шаги цикла приписываются разным потокам Компромисс между двумя противоположными целями: –Наилучший баланс загрузки потоков –Минимальное дополнительное время, потраченное на обработку цикла N N/2 C f Один поток schedule(static) schedule(dynamic, c) schedule(guided, f)
22 Упражнение 7: планирование Усовершенствуйте схему планирования Скомпилируйте и перепрофилируйте Добейтесь оптимальной загрузки потоков при минимальных дополнительных затратах на обработку цикла
23 Сведение Можно ли сделать лучше, чем синхронизировать все доступы к одному общему накопителю? Альтернатива: –Частный накопитель в каждом потоке –Для получения окончательного значения все частные накопители суммируются (сводятся к одному) в конце Операции сведения: +, *, -, &, ^, |, &&, || int a[N], sum = 0; #pragma omp parallel for reduction(+: sum) for (int i = 0; i < N; i++) { sum += a[i]; // no synchronization needed }
24 Упражнение 8: сведение Используйте прагму «reduction», чтобы избавиться от синхронизации и связанных с ней дополнительных задержек Скомпилируйте и спрофилируйте Подготовьте непрофилированную версию и проведите окончательные замеры Поздравляем!
25 Прагмы OpenMP на заметку Основная прагма, порождает группу потоков –omp parallel Прагмы, разделяющие задачу (можно объединять с прагмой parallel ) –omp sections –omp for Клаузулы для прагм, разделяющий задачу –private, shared, reduction – область действия переменных –schedule – управление планированием Прагмы синхронизации –omp critical [имя потока] –omp barrier
26 Решение #pragma omp parallel for private(cand, max_div, div) \ reduction(+: counter, count31) \ schedule(guided, 10) for (cand = from; cand
27 Что еще есть в OpenMP ? Другие способы определения областей действия переменных и их инициализации Более сложные прагмы синхронизации OpenMP API и переменные окружения –Контроль количества потоков –Ручная низкоуровневая синхронизация… Модель «очереди задач» для разделения задания –Расширение, специфичное для Intel и пока не стандартизованное Совместимость с Win32* и P-потоками
28 «Очередь» для разделения задачи Для более сложных интерактивных моделей, не укладывающихся в рамки обычных циклов struct Node { int data; Node* next; }; Node* head; for (Node* p = head; p != NULL; p = p->next) { process(p->data); } Node* p; #pragma intel omp taskq shared(p) for (p = head; p != NULL; p = p->next) //only 1 thrd { #pragma intel omp task process(p->data); // queue task to be executed } // on any available thread
29 Итоги и выводы Технология Hyper-Threading повышает производительность процессора при очень низких затратах Технология HT доступна сегодня на массовых настольных ПК Для извлечения преимуществ технологии HT, разбивайте на потоки Ваше приложение! Используйте OpenMP для легкого поэтапного распараллеливания Вашего приложения! Для достижения максимальной производительности используйте Intel Threading Tools
30 Полезные ресурсы developer.intel.com/software/products/ compilers/ Руководство Intel ® Compiler User Guide
31 Спасибо за внимание! developer.intel.com Пожалуйста, не забудьте вернуть заполненные анкеты
32 Дополнительные материалы
33 Использование распараллеливания Уровень распараллел ивания Где используетсяТехнологияПроблема КомандыГиперконвейерные, сложные исполнительные устройства, предсказание ветвлений Микроарх. Intel NetBurst® (гиперконвейерная, суперскалярная, спекулятивная) Использование ДанныеSIMDMMX, SSE, SSE2Область действия Задача, поток Несколько процессоров SMPЦена
34 Опции Intel ® Compiler для многопоточности и OpenMP Автоматическое распараллеливание –/Qparallel Поддержка OpenMP –/Qopenmp –/Qopenmp_report{0|1|2}
35 Ключевые термины Многопроцессорность (MP) –аппаратная технология для повышения производительности за счет увеличения числа процессоров Технология Hyper-Threading (HT) –аппаратная технология для повышения производительности за счет более оптимального использования ресурсов процессора Многопоточность (MT) –программная технология для повышения функциональности и производительности ПО за счет использования нескольких (логических) процессоров
36 HT - технология, никакой мистики Арх. сост. Несколько процессоров Hyper-Threading Арх. сост. Кэш-память Проц. Блок исполнения команд Кэш-память Проц. Блок исполнения команд Кэш-память Проц. Блок исполнения команд Технология HT повышает производительность процессора благодаря лучшему использованию ресурсов
37 Технология HT: что внутри Instruction TLB Указатель следующей команды Буферы потоковых команд Trace Cache Fill Buffers Таблицы псевдонимов регистров Trace Cache Next IP Return Stack Predictor Технология HT повышает производительность процессора при минимальных затратах
38 HT: использование преимуществ HT прозрачна для ОС и приложений –ПО просто «видит» несколько процессоров Способы использования ПО для извлечения преимуществ от технологии HT: –Многопоточность – в пределах одного приложения –Многозадачность – среди нескольких приложений Поддержка со стороны ОС увеличивает преимущества технологии HT: –тонкое планирование с учетом логических процессоров –остановка логических процессоров в пустом цикле –внедрена в: Windows* XP, Linux* 2.4.x Для использования преимуществ технологии HT разбивайте Ваше приложение на несколько потоков!
39 Что? Стратегия многопоточности Как? Внедрение многопоточности Разбивайте Ваше приложение на несколько потоков
40 Распараллеливание задачи Разделите всю задачу на несколько несвязанных друг с другом задач Исполняйте эти задачи одновременно (отдельными потоками) Поток сжатия Поток шифрования Data Данные
41 Распараллеливание данных Поток A Поток N … Разделите данные на несколько несвязанных друг с другом наборов Назначьте эти наборы одновременно исполняемым потокам
42 Внедрение многопоточности API / Библиотека –Win32* API –P-потоки –MPI Языки программирования –Java* –C# Расширение языков программирования –OpenMP