Модели многопроцессорной системы и задачи.
Рис. 1. Пример модели трехпроцессорной системы.
Каждый
процессор, полагается, имеет некоторый набор двунаправленных портов процессоров.
Рассмотрим средства описания модели вычислительной системы на примере системы 3L Parallel C.
processor <идентификатор процессора>
Специфицированы должны быть все
процессоры системы, включая корневой процессор (в виде processor host).
wire? <спецификатор порта> <спецификатор порта>
Пусть, например, в системе имеется два
процессора с именами
proc_one,
proc_two и каждый из этих процессоров имеет по 4 двунаправленных порта с номерами 0 – 3. Тогда спецификация
processor proc_one
processor proc_two
wire? proc_one[2] proc_two[3]
задает топологию системы, которая приведена на рис.2.
Рис. 2. Пример топологии вычислительной системы.
Модель задачи. Каждая задача имеет два вектора портов входа задачи и портов выхода задачи (см. рис. 3). Из входных портов задача может читать сообщения, а в выходные порты — отправлять сообщения.
Обычно используется также простая модель программы в виде множества задач, имеющих взаимосвязанные входные и выходные порты. Пример модели программы приведен на рис. 4. Программа здесь состоит из 4-х задач

—

, из которых задача

имеет два выходных порта, задача

– входной и выходной порты, задачи

,

– по одному входному порту.
Рис. 4. Пример модели программы.
Рассмотрим средства описания модели задачи на примере системы 3L Parallel C.
Оператор
TASK предназначен для описания задач и имеет
синтаксис
task <идентификатор задачи> {<атрибуты задачи>}
Атрибуты задачи включают в себя, в частности
- INS =<const> — количество входных портов задачи (обязательный атрибут);
- OUTS =<const> — количество выходных портов задачи (обязательный атрибут);
- FILE = <имя файла>, в котором находится объектный код задачи (необязательный атрибут);
- DATA = <требуемый размер памяти> (необязательный атрибут);
- ………..
Оператор
CONNECT объявляет логические связи межу портами двух задач и имеет
синтаксис
connect?<спецификатор входного порта задачи> < спецификатор выходного порта задачи>
Пусть, например, программа состоит из двух задач с именами task_1, task_2, каждая из которых имеет по одному входному порту (INS=1) и одному выходному порту (OUTS=1) с номерами 0, 1, соответственно. Тогда спецификация
task task_1,INS=1,OUTS=1
task task_2,INS=1,OUTS=1
connect? task_1[1] task_2[0]
connect? task_2[1] task_1[0]
задает топологию связи задач, приведенную на рис. 5.
Рис. 5. Пример топология связей программы, состоящей из двух задач.
Отображение задач на процессоры.
Оператор
PLACE определяет
процессор, на котором должна быть выполнена задача.
Синтаксис оператора:
place <имя задачи> <имя процессора>
Пусть, например, программа имеет топологию связей задач, приведенную на рис. 5, и должна исполняться на вычислительной системе, изображенной на рис.2. Тогда
отображение программы на
архитектуру вычислительной системы может быть реализовано спецификацией (см. Рис. 6)
place task_1 processor_one
place task_2 processor_two
Рис. 6. Пример отображения программы на архитектуру вычислительной системы.
"Процессорная ферма"
При использовании
средств конфигурирования, аналогичных рассмотренным выше, описание топологии вычислительной системы, топологии программы и
отображение программы на
вычислительную систему оформляются в виде конфигурационного
файла. Написание конфигурационного файла является трудоемкой процедурой. Но основная проблема заключается в другом – при изменении конфигурации используемой вычислительной системы требуется изменение конфигурационного файла (проблема переносимости параллельного
программного обеспечения).
Одним из решений проблемы переносимости является следующий подход. Программы разрабатываются в ориентации на некоторую простую, фиксированную
логическую структуру
коммуникационной сети процессоров. Средствами операционной системы параллельной
ЭВМ поддерживается
отображение этой логической структуры на физическую структуру ЭВМ. При этом пропадает необходимость в написании конфигурационного
файла.
Рис. 7. Логическая структура сети "процессорная ферма". P0 – master-процессор; P0, P1, ..., Pn — slave- или worker-процессоры.
Имеется жесткое ограничение на логическую организацию программы, которая должна исполняться на "
процессорной ферме". Программа должна состоять из совокупности одинаковых задач, каждая из которых выполняется на своем подчиненном
процессоре, и из основной задачи, которая выполняется на
master-процессоре. Другими словами, все
slave-процессоры или
worker-процессоры 
должны выполнять одну и ту же задачу (но, разумеется, над разными данными), а master-процессор должен выполнять задачу, которая распределяет исходные данные между рабочими процессорами, получает от этих процессоров результаты и, возможно, обрабатывает их, отображает и сохраняет.
При изменении числа
процессоров реконфигурация прикладной программы не нужна.
Обмен данными между P- задачами и M- задачей выполняется с помощью двух операций типа SEND, RECEIVE.
Если операция
SEND выполняется M-задачей, то она вызывает пересылку данных из этой задачи первому свободной в данный момент
подчиненному процессору. Если эта операция выполняется P-задачей, то она пересылает данных из этой задачи M-задаче.
Аналогично, если операция RECEIVE вызывается M-задачей, то она читает очередной пакет данных, передаваемый P-задачей. Если эта операция выполняется P-задачей, то она читает пакет сообщения, передаваемый M-задачей.
Операционная система используемой параллельной
ЭВМ должна обеспечивать сохранение того же порядка поступления элементов сообщения, состоящего из нескольких пакетов, что и при их передаче.
В качестве примера рассмотрим операции обмена данными между P- задачами и M- задачей в
языке 3L Parallel C.
Язык 3L Parallel C использует для этого обмена две библиотечных функции:
1) функция типа SEND
int net_send(nbytes, packet, complete)
где nbytes – количество передаваемых данных в байтах, packet – имя массива передаваемых данных, complete=0 – признак того, что сообщение длинное (разбито на ряд пакетов и данный пакет является не последним), complete=1 – признак того, что данное сообщение представляет последний или единственным пакет. Функция возвращает количество переданных байтов nbytes;
2) функция типа RECEIVE
int net_receive(packet, complete)
с аналогичными аргументами.