<<< BACK NEXT >>>

ВВЕДЕНИЕ

Параллельные вычисления – современная многогранная область вычислительных наук, бурно развивающаяся и являющаяся наиболее актуальной в ближайшие десятилетия. Актуальность данной области складывается из множества факторов, и в первую очередь, исходя из потребности в больших вычислительных ресурсах для решения прикладных задач моделирования процессов в физике, биофизике, химии и др. К тому же, традиционные последовательные архитектуры вычислителей и схем вычислений в преддверии технологического предела. В то же время технологический прорыв в области создания средств межпроцессорных и межкомпьютерных коммуникаций позволяет реализовать одно из ключевых звеньев параллелизма – эффективное управление в распределении вычислений по различным компонентам интегрированной вычислительной установки. Заметим, что развитие квантовых вычислителей и вычислений находится в стадии исследований, и вряд ли стоит ожидать появления промышленных образцов таких вычислителей в ближайшие 20-30 лет. То есть, ближайшие десятилетия пройдут под знаменем развития и распространения параллельных архитектур, средств описания и реализации параллельных вычислений.
   История параллельных вычислений начиналась с некоторым, не очень значительным опозданием от начала возникновения концепций последовательных вычислений. Вероятно, к первой и наиболее целостной модели параллельных вычислений можно отнести концепцию клеточных автоматов Дж. Фон Неймана ([]). В то же время инженерно-конструкторские работы над такими проектами вычислителей, как ILLIAC-III (позже, ILLIAC-IV), CRAY-I, STAR-100 и STARAN были ориентированы на использование параллельных схем реализации программ (перечисленные проекты начиналась в 50-х годах).
   Начало теоретическим исследованиям параллельных вычислений положила известная работа Карпа и Миллера [1], предопределившая множество вариаций на тему формальных и автоматных схем описания параллельных вычислений [2]. Предложенные варианты представления параллельных вычислений выявили множество свойства и проблем, присущих только параллелизму и не характерных для последовательных вычислений (устойчивость и однозначность, конечной задержки и пр. – см. работы Деннинга [3]).
   Одновременно, были определены фундаментальные подходы к параллельной алгоритмизации: глобальный и “близорукий”, потоковой (data-flow) и операторной схемам реализации вычислений. Кроме того, обозначились принципиальные подходы к проблеме программирования параллельных вычислений: автоматическое распараллеливание программ и императивное/директивное программирование параллельных вычислений, мелкозернистое и крупнозернистое распараллеливание программ.
   Современные исследования и работы сконцентрированы, в основном, на разработке многоядерных процессоров и многопроцессорных систем (Intel, AMD, IBM), процессоров с интеграцией специализированных подпроцессоров (DSP-процессоры, нейронные процессоры и т.п., производимые HP, TI и другими компаниями). Комплексные решения, в основном, заключаются в построении кластеров, интегрирующих как многопроцессорные, так и однопроцессорные компьютеры.
   Резюмируя данный экскурс надо отметить, что на фоне бурного роста технических решений математическое обеспечение в области организации и реализации параллельных вычислений остается крайне проблемной, во многом, открытой областью. Проблемы и принципы решений в  этой области – основной предмет обсуждения в данной работе. В частности, следующие: каковы основания параллельных вычислений и какова предпочтительная актуальность автоматического распараллеливания программ и средств параллельного программирования; какими свойствами должны обладать средства параллельного программирования.

Предпочтения методу при создании параллельных программ диктуются  принципиальными свойствами и различиями при алгоритмизации параллельных и последовательных вычислений. Основой любого распараллеливания является наличие независимых групп данных, которые могут быть подвергнуты одновременной обработке, а также - наличие в алгоритме функционально и информационно независимых процедурных единиц, которые также могут быть выполнены одновременно. Стремление осуществить декомпозицию алгоритма с целью получения независимых групп данных часто связано с дроблением или дублированием структур данных, что противоречит основным принципам последовательного программирования, где эффективность программ достигается в том числе через  минимизацию используемых в программах данных (эффективность по памяти) и минимизации процедурных единиц (дробление однородной совокупности данных приведет к возникновению дополнительному программированию по управлению фрагментами, что с точки зрения последовательных алгоритмов выглядит нелепо). В то же время, построение алгоритма по последовательной схеме обработки данных так или иначе приводит к последовательному построению вызовов функциональных процедур обработки этих данных. Одновременная множественная обработка единообразных данных требует либо специальной организации в агрегировании данными внутри самих процедур обработки (для реентерабельных процедур необходима особая организация всего пула локальных переменных, внимательная работа с переменными, созданными на статической основе), либо же копированием и/или распределением исполняемых процедур по разным вычислителям с исключением возможности использования общих полей памяти. В то же время, декомпозиция задачи при “параллельном мышлении” должна осуществляться с учетом возможности одновременного исполнения тех или иных процедур.
   Таким образом, концепции и критерии последовательной и параллельной алгоритмизации и программирования противоречат друг другу. И как следствие, незначительность результатов в области автоматического распараллеливания последовательных программ (от 10 до 20 процентов ускорения). В целом, это направление носит коммерческо-технологический характер и реализует стремление адаптировать уже разработанное программное обеспечение к новым архитектурам. К тому же, существует проблема перестройки мышления разработчиков программного обеспечения: параллельные алгоритмы требуют особого осмысления задач в части их декомпозиции, алгоритмизации и программирования. Резюмируя, автоматическое распараллеливание программ – направление переходного этапа от последовательных схем вычислений к параллельным.
   Наиболее корректным и, безусловно, перспективным является создание средств параллельного программирования и инструментальных сред разработки программ. Данные средства могут быть узко ориентированными на конкретную параллельную архитектуру, либо носить относительно универсальный характер (эффективно охватить все возможные интерпретации параллельных схем вычислений практически невозможно).

   Какие же задачи должен решать язык параллельного программирования, и какие задачи решаются при реализации собственно параллельных вычислений?
   Потенциал языка программирования должен обеспечить возможность выразить принцип параллельной схемы реализации программы, обеспечить адекватную структуризацию данных, формирование такой структуры программы, которая отвечает заданным принципам распределения процедурных фрагментов для распределенного исполнения. 
   Реализация задач распределения командных/процедурных фрагментов программы по исполнительным устройствам вычислительной установки, а также задач распределения данных и интеграции всего событийного ряда обеспечивают исполнение вычислений. Решение этих вопросов напрямую зависит от того, какова идейная основа обработки данных. В целом, это двуединая диалектическая проблема: структурирование данных в известном смысле предопределяет процедурную основу и в то же время процедурное начало задает направленность к адекватной структуризации данных.  
   Важнейшей составляющей практически для всех параллельных архитектур является возможности миграции данных и фрагментов программ. Миграция данных может присутствовать явно или неявно и крайне важна в первую очередь для архитектур с явно или неявно разделяемой памятью. В то же время структурное представления алгоритма и соответствующей программы во многом определяет возможность по распределению программы по исполняющим ее устройствам. Требование к возможности миграции фрагментов программ приводит к идее о представлении программы и ее фрагментов в качестве структуры данных. Возможность представления программ в качестве структур данных обеспечивает еще одно важное свойство – возможность доступа к компонентам программы как к данным, а следовательно – возможность изменения программ в процессе вычисления, в том числе – самоизменения.
   Императивное параллельное программирование (запуск параллельных процессов по прямому требованию инструкцией программы) также требует особых подходов к вопросам структуры программы. В первую очередь это связано с тем, какой метод распараллеливания будет выбран. Вопрос крайне субъективный и зависит от множества факторов. Здесь учитывается в первую очередь схема и скорость распараллеливания на заданной вычислительной установке. Мелкозернистое распараллеливание (уровень распараллеливания не выше инструкций/команд) требует более частого включения блока распараллеливания, чем при крупнозернистом распараллеливании (уровень процедур и выше). На сегодняшний день в большинстве случаев используется распараллеливание на уровне модулей, или внутрикомандное распараллеливание – декомпозиция аппаратными средствами одной команды на субкоманды и их распределение по специализированным подпроцессорам (векторно-конвейерные вычислители типа Cray и другие, или же аппаратное разделение машинных команд по специализированным процессорам (DSP процессоры, конвейерные процессоры).  Однако, мелкозернистое распараллеливание свойственно системам с автоматическим распараллеливанием на уровне компиляторов языков высокого уровня или на уровне языков ассемблеров или автокодов.  
   Автоматическое распределение имеет две стилистики решения: статическую, по итогам компиляции исходного кода, и динамическую, с помощью средств выявления потенциально параллельно исполнимых фрагментов исполняемого кода и распределения этих фрагментов по процессирующим элементам. Динамическое распараллеливание позволяет более эффективно выявлять параллельно исполнимые компоненты, однако является крайне затратным по времени исполнения: как правило, ведется постоянный мониторинг линейных (или линеаризируемых) участков программ с целью выявления возможных одновременно выполнимых инструкций программы.
   Еще один комплекс проблем связан с категорией события в параллельных вычислениях. Это – способы интеграции событийного поля в распределенных архитектурах, организация процесса реагирования на события.

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

<<< BACK NEXT >>>