С появлением сложных математических и физических задач, решаемых на компьютерах были разработаны соответственно машины, имеющие "векторную" или "матричную" архитектуру. Такие ЭВМ представляют, на самом деле, несколько процессоров, достаточно автономных, но способных обмениваться между собой информацией о результатах своих вычислений. Достаточно хорошим приближением к таким архитектурам являются сети компьютеров с возможностью распределенных вычислений. Кроме этого, практически все современные микропроцессоры максимально используют в своей архитектуре возможности параллельного исполнения отдельных операций. Таким образом, параллелизм можно мысленно разбить на два уровня: параллелизм уровня микроопераций и параллелизм уровня процессов.
Процессы - это абстракция достаточно высокого уровня. В какой вычислительной модели работает каждый отдельный процесс - не принципиально. Важно, что они могут работать параллельно, и могут обмениваться между собой результатами своих вычислений через "каналы связи". Примерно такую модель взаимодействия процессов реализует язык параллельного программирования Occam. Вот некоторая грамматика описания процессов, достаточно близкая к принятой в Occam-е:
Процесс ::= Простой процесс | Структурный процесс
Простой процесс ::= Послать значение | Принять значение | Процесс вычислительной модели
Структурный процесс ::= Последовательный процесс | Параллельный процесс
Послать значение ::= Канал связи << Выражение ;
Принять значение ::= Канал связи >> Выражение ;
Процесс вычислительной модели ::= нечто, определяемое конкретным вычислителем
Последовательный процесс ::= seq Процесс* end
Параллельный поцесс ::= par Процесс* end
Семантически взаимодействие параллельных
процессов лучше всего представлять как работу сети неких устройств,
соединенных "проводками", по которым текут данные. Спроектировав в таких
терминах, например, систему параллельных процессов для быстрого
суммирования большого количества чисел, можно легко описать эту систему в
приведенном синтаксисе.
Каждый вычислитель производит типичные для
его вычислительной модели операции (например, императивный вычислитель
будет переходить из состояния в состояние). Когда процесс встречает
инструкцию "Принять значение (из канала)", он входит в состояние
ожидания, пока канал пуст. Как только в канале появляется значение,
процесс его считывает и продолжает работу.
Достаточно распространенной является так
же и следующее понимание параллелизма: в системе параллельных процессов
каждый отдельный процесс обрабатывает события. События могут быть как
общими для всей системы, так и индивидуальными для одного или нескольких
процессов. В таких терминах достаточно удобно описывать, например,
элементы графического интерфейса пользователя, или моделирование
каких-либо реальных процессов (например, управление уличным движением) -
так как понятие события является для таких задач естественным. Такое
программирование принято называть событийно-управляемым. В
событийно-управляемом программировании отдельные процессы максимально
автономны, единственное средство общения между ними - посылка сообщений
(порождение новых событий). Событийно-управляемое программирование очень
близко к объектно-ориентированному программированию, которое будет
подробно разобрано в дальнейшем.
Параллелизм является не только
надстройкой над другими вычислительными моделями; некоторые методологии
программирования имеют естественную реализацию на платформах,
поддерживающих параллелизм. Об этом будет упомянуто отдельно в каждом
таком случае.