Передача сообщений улучшает масштабируемость параллельных систем Рассел Уиндер

Уже на первых лекциях по информатике программистов учат, что конкурентные вычисления — и в особенности параллельные как особый подвид конкурентных — вещь трудная, и что лишь лучшим дается надежда справиться с этой задачей, и что даже лучшие не справляются. При этом неизменно уделяется большое внимание потокам, семафорам, мониторам и трудностям организации потоковой безопасности при одновременном доступе к переменным.

Сложных проблем здесь действительно много, и решать их бывает очень трудно. Но в чем корень проблем? Общая память. Практически все проблемы конкурентных вычислений, о которых постоянно приходится слышать, касаются общей памяти с изменяемыми данными: состояние гонки (race conditions), взаимная блокировка (deadlock), активная блокировка (livelock) и т. п. Кажется, ответ очевиден: забудьте о конкурентности либо держитесь подальше от общей памяти!

Отказ от конкурентности почти наверняка не вариант. Количество ядер в компьютерах возрастает чуть ли не каждый квартал, поэтому достижение настоящего параллелизма становится все важнее. Мы не можем больше полагаться на непрерывный рост тактовой частоты процессоров как основу производительности приложений. Производительность может вырасти только за счет параллелизма. Конечно, можно не заботиться о производительности приложений, но едва ли это понравится пользователям.

Так можно ли отказаться от общей памяти? Определенно, да.

Вместо потоков и общей памяти можно воспользоваться процессами и передачей сообщений. Под процессом здесь понимается защищенное независимое состояние исполняющегося кода, а не обязательно процесс операционной системы. Такие языки, как Erlang (а до него occam), показали, что процессы — весьма удачный механизм программирования конкурентных и параллельных систем. В таких системах меньше проблем синхронизации, чем в многопоточных системах с общей памятью. Кроме того, существует формальная модель взаимодействующих последовательных процессов (Communicating Sequential Processes, CSP), которую можно применять при разработке таких систем.

Можно пойти дальше и организовать вычисления в виде системы, управляемой потоком данных (dataflow system). В такой системе нет явно запрограммированного потока управления. Вместо этого создается направленный граф операторов, соединенных путями передачи данных, а затем в систему подаются данные. Контроль вычислений осуществляется по готовности данных внутри системы. И никаких проблем синхронизации.

При этом для системной разработки применяются главным образом такие языки, как C, C++, Java, Python и Groovy, о которых программистам говорят, что они служат для разработки многопоточных систем с общей памятью. Как же быть? Решение в том, чтобы использовать — или создавать, если их не существует, — библиотеки и среды, которые предлагают схемы процессов и пересылки сообщений, полностью исключающие применение общей изменяемой памяти.

В итоге отказ от общей памяти в пользу передачи сообщений станет, скорее всего, наиболее удачным методом реализации систем, эффективно использующих параллелизм, получивший сегодня повсеместную прописку в компьютерном железе. Занимательно выходит — процессы как единица конкурентного исполнения появились раньше потоков, но в будущем, по-видимому, потоки станут использоваться для реализации процессов.

Загрузка...