Рейтинговые книги
Читем онлайн Параллельное и распределенное программирование на С++ - Хьюз Камерон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 89 90 91 92 93 94 95 96 97 ... 181

$ mpirun -np 16 /trap/search_n_rescue

// Листинг 9.5. Реализация MPI-задачами простого

// поиска и имитации спасения поврежденных

// объектов

template<T> bool travel(vehicle *Transport,

set<T> Location, T Object)

{

//.. .

Transport->startEngine(); Transport->moveForward(XDegrees); Transport->turnLeft(YDegrees); //.. .

if (Location.find(Transport->location() == Object){ // . .. rescue()

}

//.. .

}

int main(int argc, char *argv[])

326 Глава 9. Реализация моделей SPMD и MPMD с помощью шаблонов..

{

//...

int Tag = 2; int WorldSize; int TaskRank; MPI_Status Status; MPI_Init(&argc,&argv);

MPI_Comm_rank(MPI_COMM_WORLD, &TaskRank); MPI_Comm_size(MPI_COMM_WORLD, &WorldSize); //. . .

switch(TaskRank) {

case 1: {

//. . .

car * Car;

set<streets> SearchSpace

travel<streets>(Car, SearchSpace,Street); //.. .

}

break;

case 2:

{

//.. .

helicopter *BlueThunder; set<air_space> NationalAirSpace; travel<air_space>(BlueThunder,

NationalAirSpace,

AirSpace);

//.. .

}

//case n: //. . .

}

}

Программа search_n_rescue будет запущена в 16 процессах, причем все процессы потенциально могут выполняться на различных процессорах, а все процессоры — находиться на различных компьютерах. Несмотря на то что все процессы выполняют один и тот же код, их действия могут радикально различаться (как и данные, с которыми они работают). Шаблоны и полиморфизм позволяют отличать одну MPI-задалу от другой (а значит, и данные, которые они будут использовать). Обратите внимание на то, что в листи н ге 9.5 МРI - процесс, у которого TaskRank = 1, будет использовать объект класca Car и контейнер, содержа щ ий streets - объекты . MPI-процесс, у которо г о TaskRank = 2, будет использовать объект класса helicopter и аir_spасе объекты. Обе задачи вызывают шаблонную функцию travel (). Поскольку шаблоннал функция travel () манилулирует указателями на класс vehicle, она может воспользоваться преимущест-вами полиморфизма и выполнять операции с потомками класса vehicle. Это означает, что, хотя все MPI-задачи вызывают одну и гу же функцию travel (), действия, вы полняемые этой функцией, рааличны. Обратите внимание на то, что в функции travel () нет инструкций case или if, которые бы пытались идентифицировать тип vehicle -объекта, с которым она работает. Конкретный vehicle -объект определяется типом, на который используется указатель. Это MPI-приложение может работать потенциально с 16 различными транспортными средствами, каждое из которых характеризуется собственным типом мобильности и областью поиска. Существуют и другие методы, которые можно использовать для реализации модели MPMD в среде MPI, но полиморфический подход обычно требует меньшего объема кода.

Основные два типа полиморфизма, которые мы здесь демонстрируем, — это полиморфизм динамического связывания, по д держиваемый наследованием и виртуальными методами, и параметрический полиморфизм, по д держиваемый шаблонами. Функция travel () в листин г е 9.5 использует оба типа полиморфизма. Полиморфизм, основанный на наследовании, характеризует параметр vehicle *Transport, а параметрический полиморфизм — параметры set<T> и T Object. Параметрический полиморфизм представляет собой механизм, благодаря которому один и тот же код используется для различных типов, передаваемых в качестве параметров. Различные типы полиморфизма, которые позволяют упростить МРТзадачи и сократить код, необходимый для реализации MPI-программы, перечислены в табл. 9.2.

Таблица 9.2. Различные типы полиморфизма, которые можно использовать  для упрощения МРI-задач

Типы полиморфизма

Механизмы

Описание

Динамический

Наследование и виртуальные методы

Вся информация, необходимая для определения того, какие виртуальные методы будет вызывать функция, неизвестна до выполнения программы

Параметрический

Шаблоны

 Механизм, в котором один и тот же код используется для различных типов, которые передаются как параметры

Введение MPMD-модели c помощью функций -объектов

Функции-объекты используются в стандартных алгоритмах для реализации горизонтального полиморфизма. Полиморфизм, реализованный с помощью передачи параметра vehicle *Transport в листинге 9.5, является вертикальным, поскольку для функционирования необходимо, чтобы классы были связаны наследованием. При горизонтальном полиморфизме классы связаны не наследованием, а интерфейсом. Все функции-объекты определяют операторную функцию operator (). Функции-объекты позволяют разрабатывать MPI-задачи с использованием некоторой общей формы.

// Функция-объект class some_class{ //.. .

operator(); //

};

template<class T> T mpiTask(T X) {

//

Т Result; Result = X() //. . .

}

Шаблонная функция mpiTask () будет работать с любым типом T, который имеет соответствующим образом определенную функцию operator ().

//. . .

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &TaskRank); MPI_Comm_size(MPI_COMM_WORLD, &WorldSize); //. . .

if(TaskRank == 0){ //. . .

user_defined_type M; mpiTask(M); //.. .

}

if(TaskRank == N){ //.. .

some_other_userdefined_type N; mpiTask (N) ;

}

//----

Этот горизонтальный полиморфизм не имеет отношения к наследованию или виртуальным функциям. Поэтому, если наша MPI-задача получит свой ранг, а затем объявит тип объекта, в котором определена функция operator (), то при вызове функции mpiTask () ее поведение будет продиктовано содержимым метода operator (). Тогда, несмотря на идентичность всех процессов, запу щ енных посредством сценария mpirun, полиморфизм шаблонов и функций-объектов позволит всем MPI-задачам выполнять различную работу над различными данными.

Как упростить взаимодействие между MPI-задачами

Помимо упрощения и сокращения размеров кода МРТзадачи с помощью полиморфизма и шаблонов, мы можем также упростить взаимодействие между MPI-задачами, воспользовавшись преимуществами перегрузки операторов. Функции MPI_Send () и MPI_Recv () имеют следующий формат:

MPI_Send(Buffer, Count, MPI_LONG, TaskRank, Tag, Comm);

MPI_Recv(Buffer,Count,MPI_INT, TaskRank, Tag, Comm, &Status);

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

Таблица 9.3 Прототипы MPI-функций отправки и приема данных

ФункцииОписание

#include «mpi.h»

int MPI_Send (void *Buffer,int Count, MPI_Datatype Туре, int Destination, int MessageTag, MPI_Comm Comm) ; Выполняет базовую отправку данных

int MPI_Send_init (void *Buffer,int Count, MPI_Datatype Type, int Destination, int MessageTag, MPI_Comm Comm, MPI_Request *Request); Инициализирует дескриптор для стандартной отправки данных

1 ... 89 90 91 92 93 94 95 96 97 ... 181
На этой странице вы можете бесплатно читать книгу Параллельное и распределенное программирование на С++ - Хьюз Камерон бесплатно.
Похожие на Параллельное и распределенное программирование на С++ - Хьюз Камерон книги

Оставить комментарий