- •10.1. Виды параллельной обработки
- •10.1.1. Классификация систем параллельной обработки
- •10.2. Матричная обработка данных
- •Массив процессорных элементов
- •10.3. Архитектура мультипроцессорных систем общего назначения
- •10.4. Коммуникационные сети
- •10.5. Организация памяти в мультипроцессорных системах
- •10.6. Программный параллелизм и общие переменные
- •10.6.1. Доступ к общим переменным
- •10.6.2. Согласованность кэша
- •10.6.3. Блокировка и согласованность кэш-памяти
- •10.7. Мультикомпьютерные системы
- •10.8. Общая память и передача сообщений
- •10.8.1. Система с общей памятью
- •10.8.2. Система с передачей сообщений
- •10.9. Производительность мультипроцессорных систем
- •10.9.1. Закон Амдала
- •10.9.2. Показатели производительности
10.6. Программный параллелизм и общие переменные
Во введении к этой главе говорилось, что сложную задачу не всегда легко разбить на параллельно выполняемые подзадачи. Однако есть особые случаи, когда это сделать достаточно просто. В частности, если главная задача представляет собой набор независимых программ, эти программы легко выполнить на разных процессорах. И если программы не блокируют друг друга, соревнуясь за устройства ввода-вывода, мультипроцессор оказывается полностью загруженным.
Кроме того, программу легко разделить на параллельно выполняемые задачи при использовании языка высокого уровня, позволяющего программисту явно выделить отдельные задачи. Такая конструкция часто называется PAR-сегментом. Она показана на рис. 10.13. Между управляющими командами PARBEGIN и PAREND находится список процедур, от Proc1 до ProcК, которые могут выполняться параллельно. Рассмотрим порядок реализации этой программы. После завершения сегмента программы, предшествующего команде PARBEGIN, может немедленно начаться выполнение любой из К параллельных процедур или же всех этих процедур, что зависит от количества свободных процессоров. Последовательность их запуска может быть любой. Выполнение части программы, следующей за командой PAREND, разрешается только после завершения выполнения всех или К параллельных процедур.
PARBEGIN
Proc1;
Proc2;
….. PAR-сегмент
ProcК;
PAREND
…..
Рис. 10.13. Программная конструкция для параллельного выполнения
Если мультипроцессорная система выполняет только эту программу, за эффективное использование процессоров отвечает программист. Степенью параллелизма PAR-сегментов К, и отношением их общего размера к размеру последовательных сегментов определяется эффективность работы мультипроцессорной системы.
Наиболее эффективное использование мультипроцессорных систем достигается путем применения компиляторов, способных автоматически определять фрагменты пользовательских программ, которые можно запускать параллельно. Программист обычно представляет программу как набор последовательно производимых операций. Но, несмотря на это, существует много возможностей параллельной реализации различных групп команд. Простейшим примером является многократно выполняемый программный цикл. Если данные, используемые на разных итерациях, независимы, итерации можно осуществлять параллельно. Если же при первом прохождении по циклу генерируются данные для второго прохождения и т. д., параллельная работа не возможна. Компилятор должен выявлять зависимости по данным и решать, какие операции можно выполнить параллельно, а какие — нельзя. Разработка компиляторов, разбивающих программу на параллельно выполняемые фрагменты, — задача не из простых. И даже после того, как такие фрагменты будут выделены, их еще нужно оптимально распределить между процессорами, так как свободных процессоров может быть меньше, чем фрагментов. Мы не будем обсуждать вопрос распределения подзадач между процессорами и планирования последовательности их реализации, а лишь поговорим о доступе к общим переменным, которые модифицируются параллельно выполняемыми подзадачами в мультипроцессорной системе.