
Лекции / Лекция 8
.docТехнологии и методы программирования. Лекция 8.
Оценка информационных зависимостей.
Информационные зависимости возникают при синхронизации выполнения подзадач. При этом неизбежна трата ресурсов — и, если она слишком велика, необходимо вернуться к декомпозиции. Затраты на информационные зависимости определяются как время передачи сообщений, а так же по критериям оценки зависимостей:
- локальные или глобальные? Локальные зависимости — обмен информацией только между двумя узлами, глобальные — между всеми. Локальные предпочтительнее.
- структурные или произвольные? Структурные зависимости выполняются по стандартным схемам.
- статический или динамический режим обмена сообщениями? При статическом план обмена сообщениями известен заранее, при динамическом — определяется в момент вычисления.
- синхронные или асинхронные сообщения? Синхронные сообщения проще программировать, асинхронные могут быть быстрее.
По этим критериям качественно оцениваются зависимости. Также существуют эвристики для оценки функциональных связей в проекте. Положительный ответ на вопрос означает хорошую оценку.
- соответствует ли временная сложность подзадач коммуникационным затратам? Она должна быть много больше затрат, иначе подзадачи необходимо слить.
- одинаковы ли коммуникационные затраты для разных подзадач? Если присутствует различие на порядок — можно задуматься о слиянии.
- является ли схема взаимодействия локальной?
- не препятствуют ли информационные зависимости параллельному решению подзадач?
Масштабирование.
Масштабирование необходимо, если число подзадач не равно числу используемых вычислительных узлов. Для сокращения числа подзадач выполняется агрегация, а для увеличения их числа — декомпозиция. В любом случае необходимо следить за следующими эвристиками:
- не ухудшается ли локальность вычислений после масштабирования?
- имеют ли подзадачи по-прежнему одинаковую временную сложность вычислений и коммуникационные затраты?
- можно ли сделать число подзадач равным числу узлов?
- зависят ли параметрически правила масштабирования от количества используемых узлов?
Если масштабирование неэффективно, возвращаемся к декомпозиции, выбирая другие (как правило, более мелкие) подзадачи.
Распределение подзадач между узлами.
Специфика проектирования параллельных алгоритмов — связь с платформой. На этом шаге выполняется балансировка вычислительной модели (то есть взвешенного графа с вершинами-подзадачами, рёбрами-коммуникационными затратами) для конкретной платформы. Существует динамическая балансировка. При ней выделяется процессор-менеджер, которых распределяет подзадачи между процессорами-исполнителями. При этом исполнители, завершив подзадачу, запрашивают новую у менеджера. При этом взаимодействие между подзадачами должно быть минимально. Если используется данная схема, то для оценки эффективности системы можно применять следующие эвристики:
- не приводит ли распределение подзадач к дополнительным вычислениям?
- существует ли необходимость в этом распределении?
- не является ли менеджер «узким местом»?
Оценка ускорения и эффективности, для данной платформы.
Техномогия MPI:
- ориентирована на использование распределённой памяти. Типичная платформа — кластер, состоящий из почти независимых вычислительных узлов, имеющих свою оперативную и дисковую память, один или несколько процессоров. Программы на MPI можно выполнять и на одном процессоре, при этом вычислительные узлы моделируются. Реализации MPI: MPICH, Microsoft MPI.
Плюсы:
- обеспечение высокой мобильности программ.
- повышение эффективности, достигаемое за счёт того, что реализация максимально учитывает особенности платформы.
- невысокие затраты на разработку (много библиотек). Так, в mpi.h 120 функций, при том, что минимально необходимо только 6.
Пример:
int main(int argc, char* argv[]){
Описание Proc_Num, Proc_Rank. Другой код без MPI
MPI_Init(&argc, &argv); - инициализация
MPI_Comm_size(MPI_COMM_WORD, *Proc_num); - получение количества процессов
MPI_Comm_rank(MPI_COMM_WORLD, *Proc_Rank); - получение ранга процесса
Вычисления...
MPI_Finalize();- освобождение ресурса
Изначально запуск дополнительных процессов при вычислении не поддерживался, поэтому инициализация по-прежнему требует число процессоров, определяемое в командной строке при запуске программы. Путь к программе должен быть один и тот же на всех узлах. Если параллельные ветви реализуют разные алгоритмы, они всё равно должны быть описаны в одной программе. Каждый процессор выбирает свою ветвь исходя из ранга, определяемого MPI_Comm_rank.