.
Начертательная геометрия Геометрическое черчение Инженерная графика Интегралы Математический анализ Матрицы Производные Векторная алгебра

 

6.2. Примеры языков параллельного программирования

 

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

Ниже в качестве примеров ЯПП мы рассмотрим некоторые модельные языки, заложенные идеи в которых используют в большинстве современных языков параллельного программирования.

 

6.2.1. P-язык

 

Пожалуй, одним из первых ЯПП был матричный P-язык, разработанный в ИМ с ВЦ СО АН СССР. Программа, записанная на этом языке, представляет собой матрицу, элементами которой являются операторы, среди которых имеются операторы настройки, производящие изменение коммутаторов элементарных машин (ЭМ) либо параметров, управляющих структурой ЭМ; операторы обмена информацией между ЭМ и "пустые" операторы, пропускающие выполнение одного шага вычислений. Каждый столбец матрицы включает независимые операторы, которые можно выполнять параллельно. Процесс выполнения программы сводится к последовательному прохождению всех столбцов матрицы.

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

 

6.2.2. ЯПФ-язык

 

Более удобным в этом плане является язык ярусно-параллельных форм (ЯПФ) Д.А. Поспелова. Программа на ЯПФ представляет собой мультиграф, задаваемый, например, в матричной форме. Вершинами мультиграфа являются операторы, мультиграф не имеет контуров. Дуги данного мультиграфа бывают двух типов: информационные и управляющие. При выполнении программы на ЯПФ первоначально выделяется нулевой ярус (множество операторов, не имеющих непосредственных предшественников по информационным дугам) (рис. 6.1) и инициируется выполнение операторов из этого
множества. После их выполнения убираются все информационные дуги, выходящие из нулевого яруса, и в оставшемся графе таким же образом выделяется первый ярус.

 


Рис. 6.1. ЯПФ-представление алгоритма

 

Процесс продолжается от яруса к ярусу. После выполнения управляющего оператора, из которого выходят управляющие дуги, происходит выбор одного из операторов, в которые заходят эти дуги. Процесс обработки ЯПФ-программы завершается, когда выполнены все операторы из яруса с наибольшим номером.

Однако представление программы в ЯПФ требует "развертки" циклических участков программы, что не позволяет использовать ее как язык практического параллельного программирования.

6.2.3. К-язык

В качестве языка параллельного программирования был разработан так называемый К-язык. Суть языка: задается множество элементарных операторов и множество порождающих правил построения алгоритмов, образующие некоторое исчисление. Запись вывода в этом исчислении и является К-программой. Имеются три типа основных порождающих правил: суперпозиция, дизъюнкция, рекурренция. Правило суперпозиции означает, что результаты выполнения операторов b1, b2, ..., bk служат аргументами для некоторого оператора B. Порядок выполнения операторов b1, b2, ..., bk безразличен, что и порождает параллелизм в их выполнении. Правило дизъюнкции задает ветвление в К-программе, а правило рекурренции – цикличность. К-язык относится к языкам асинхронного типа.

 

6.2.4. Язык диспозиций

 

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

Будем задавать диспозицию D знаковой системой S, множеством операторов M = {A1, A2, ..., An} (в дальнейшем оно предполагается конечным) и графом диспозиции Г(D). Каждый оператор Ai имеет один вход и Pi выходов (S1, S2, ... , SРi). Оператор Ai осуществляет некоторое преобразование Ai текстов в знаковой системе S и проверяет серию условий w0i, w1i, ... , wki. Когда оператор Ai применяется к тексту T, он проверяет, удовлетворяет ли текст T серии условий w0i, w1i, ... , wki,и преобразует текст T по правилу Ai в текст T¢. Особую роль играет условие w0i, которое будем называть условием применимости оператора Ai. Если оно выполняется (w0= 1), то оператор работает, как было описано выше. Иначе (т. е. если w0= 0) оператор Ai оставляет текст неизменным (т. е. T¢ = T). Для каждого оператора Ai задается Pi функций:

j1i (w0i, w1i, ... , wki);

j2i (w0i, w1i, ... , wki);

. . .

jРii (w0i, w1i, ... , wki).

Каждая из этих функций может принимать два значения: 1 (возможно) и 0 (невозможно). Будем называть систему функций правильной, если для каждой функции существует, по крайней мере, один набор значений аргументов, при котором она принимает значение 1.

Графом диспозиции Г(D) будем называть связный граф, вершинам которого сопоставлены либо операторы диспозиции D, либо знак #. Вершины обладают следующими свойствами:

·  имеется только одна вершина, называемая входом диспозиции, и обозначается aвх;

·  имеется, по крайней мере, одна вершина, из которой не исходит ни одна дуга и которой сопоставлен знак #. Эти вершины называются выходами диспозиции и обозначаются aвых1, aвых2, ..., aвыхn;

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

Граф Г(D) и соответствующую ему диспозицию D назовем правильными, если выполняются следующие дополнительные требования:

·  из любой вершины графа Г существует путь, по крайней мере, в
один выход;

·  для каждой вершины графа Г существует путь, ведущий из входа в
эту вершину.

Так определенная диспозиция задает систему допустимых последовательностей преобразований текста, а именно: если задан начальный текст T0, то оператор, сопоставленный входу диспозиции aвх, проверяет условие w0i; если оно не выполнено (w0i = 0), то текст T0 не меняется; если же w0 i = 1, то к тексту T0 применяется преобразование, соответствующее данному оператору, причем до выполнения этого преобразования вычисляются значения w1i, w2i, ... wki. После преобразования текста вычисляются значения функций
j1i, j2i, ..., jрii.

Те функции jj, которые принимают значение 1, определяют дуги, исходящие из входной вершины графа диспозиции, по которым возможен переход в следующую вершину. Один из этих переходов должен быть осуществлен. Тем самым на следующем шаге процесса реализации диспозиции выбирается одна из смежных с предыдущей вершина графа Г(D).

Если все функции jj = 0, то процесс останавливается. Эта ситуация называется безрезультатной остановкой.

Оператор диспозиции, сопоставленный этой вершине, применяется к полученному тексту таким же образом, как входной оператор применяется к исходному тексту T0. Если этой вершине сопоставлен знак #, то процесс на этом заканчивается, и образовавшийся к этому моменту текст считается результатом диспозиции.

Одному и тому же начальному тексту может соответствовать несколько результатов (если один, то диспозиция однозначна).

Диспозиция называется алгоритмической, если для любого начального текста на каждом шаге возможен (а следовательно, и предписан) переход только к одной вершине графа Г(D).

Заметим, что алгоритмическая диспозиция еще не обязательно есть алгоритм, так как сами преобразования могут быть определены неоднозначно (например, марковские подстановки без указания на то, какое вхождение слова берется). Мы уже использовали понятие “реализация диспозиции”, описывая, как диспозиция преобразует исходный текст. Определим реализацию диспозиции D формально.

Будем рассматривать в графе Г(D) пути (называемые сквозными), состоящие из последовательности вершин:

al0 = aвх, al1, ..., aln, aln+1 = aвыхj,

так как ali ®  (кроме aвых1, ..., aвыхn), то каждому сквозному пути будет сопоставлена сквозная последовательность операторов , , ... , . Пусть оператор (сопоставленный вершине al1) применен к тексту T0, а каждый оператор   преобразует текст Ti-1 в текст Ti. Тогда если в сквозной последовательности операторов после применения каждого оператора   (кроме ) к тексту Ti-1 возможно применение   к тексту Ti, то данную сквозную последовательность операторов и соответствующую ей последовательность текстов T0, T1, ..., Tn будем называть реализацией диспозиции D, а текст Tn – результатом применения диспозиции к тексту T0. Этот факт будем записывать так:

.

Знак ® означает: поставлен в соответствие.

Иногда удобнее описывать метод решения ряда задач как диспозицию, а затем уже тем или иным способом переходить к алгоритмам решения этих задач. Чтобы выделить алгоритмические диспозиции, следует рассматривать только такие наборы M операторов, что для " Ai Î M не более чем одна из функций j1i, j2i, ..., jрiiпринимает значение 1 вне зависимости от набора значений аргументов.

Пример. Рассматриваются слова в алфавите Z. Задан список слов П в алфавите Z. Слово B называется возможной основой слова C, если последнее может быть представлено в виде

D1 D2 ... DnB,

где n ³ 0 и "i (Di Î П.

Требуется для каждого слова найти все его возможные основы. Пусть

Z = {a, b, c, d}, Z¢ = {Z È ®} и П = {a, ab, ba}.

Тогда возможными основами слова abacd будут слова abacd, bacd, acd, cd, а слова babcd – слова babcd, abcd, bcd, cd.

Построим диспозицию для решения этой задачи:

M = {A1, A2, A3, A4, A5}.


Граф-схема диспозиции следующая (рис. 6.2):

Рис. 6.2. Граф-схема диспозиции

 

Оператор A1 приписывает к исходному слову слева букву ®. Операторы A2, A3, A4 отделяют от слова, к которому они применяются, соответственно префиксы a, ab и ba (вместе с начальной буквой ®). Описание операторов находится в табл. 10.1.

 

6.2.5. Язык OCCAM

 

Для многотранспьютерных систем английскими учеными был создан специальный язык параллельного программирования OCCAM, детальное описание которого было дано в 1984 г. в книге "INMOS Limitid Occam Programming Manual". В отличие от ЯПП, например, Concurent Fortran или Concurent Pascal, он не построен путем расширения известных последовательных ЯП.

Теоретической основой данного языка является язык CSP (Com-municating Sequential Processes), разработанный Т. Хоаром. Основным понятием языка является процесс (примитивный, составной, именованный), напоминающий процедуры и подпрограммы обычных языков программирования.

Простейшим примитивным процессом является процесс SKIP.

Если именованный процесс имеет список формальных параметров, то они следуют в описании процесса после его имени с указанием ключевых слов VALUE, VAR и CHAN, обозначающих их природу: соответственно значение, переменная или канал.

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

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

Для описания параллельного процесса после ключевого слова PAR задаются необходимые составляющие его процессы. Выполнение параллельной композиции (PAR-процесса) состоит в выполнении каждой его компоненты до полного их завершения.

Выбор процесса для исполнения в зависимости от готовности других процессов задается через ALT-процесс.

Все имена в Occam-программе до их использования должны быть опи- саны. Описания позволяют именовать значения констант (ключевое слово DEF), переменных (ключевое слово VAR) и каналы (ключевое слово CHAN). При этом должны быть определены два параллельных процесса: передача в канал и прием из канала в области действия описания каждого канала.

В языке OССАМ существует только один вид структурированных данных – одномерный массив. В Occam-2 допускается использование двумерных и трехмерных массивов различных объектов: констант, переменных и каналов.Описание массива включает его имя, за которым в квадратных скобках записывается константное выражение:

имя [количество].

Например, выбор символов строки string [ ] через канал output будет иметь вид

PROC write. string (CHAN output, VALUE string []).

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

Пока трудно сказать, насколько мы приблизились к созданию качественного и практичного ЯПП. Все зависит от класса решаемых задач, архитектур разрабатываемых компьютеров и, естественно, подвержено фактору времени. Для ВС, содержащих небольшое число процессоров, можно с успехом использовать ЯП АЛГОПП, АДА, МОДУЛА-2, OССАМ, имеющие достаточные средства организации параллельных ветвей, синхронизации управления в параллельных ветвях и средства обмена информацией между ветвями.

 

На главную