Опубликован: 22.04.2008 | Уровень: профессионал | Доступ: платный
Лекция 5:

Программирование на языке MC#

5.4.2. Пакетный алгоритм

В данном разделе описывается модификация наивного алгоритма "решето Эратосфена", существенно улучшающая эффективность параллельной (распределенной) программы, и которая дает существенное ускорение при поиске простых чисел в длинных интервалах (например, для N >= 106 ).

Основная идея предлагаемого алгоритма заключается в переходе от использования потоков одиночных данных (потоков отдельных натуральных чисел) к потокам пакетов натуральных чисел.

Пакет - это массив натуральных чисел фиксированного размера (задаваемого в программе значением PACKAGE_SIZE ), пустые хвостовые элементы которого заполняются нулями.

При этом, функции наивного алгоритма обобщаются в данном варианте естественным образом:

  • async Sieve( handler int []() getNatPack, channel (int []) sendPrimesPack) - с помощью обработчика getNatPack получает первый пакет из потока, обрабатывает его функцией SynchronousSieve, получая пакет простых чисел head, и отправляя его по каналу sendPrimesPack; остальные пакеты из входного потока фильтруются с помощью функции filter по модулю пакета head и направляются на вход следующей в цепочке рекурсивной функции Sieve ;
  • void filter( int [] head, handler int [] () getNatPack, channel ( int []) cfiltered) - функция, которая фильтрует пакеты из входного потока, получаемые с помощью обработчика getNatPack, по модулю пакета простых чисел head, отправляя результирующие пакеты в канал cfiltered; при этом, все результирующие пакеты (кроме, может быть, последнего) имеют длину PACKAGE_SIZE (строго говоря, и последний пакет имеет длину PACKAGE_SIZE, но его хвостовая часть может быть заполнена нулями).

Полный текст программы Eratosthenes2 приведен ниже, а также в приложении [ "Программирование на языке MC#" ].

5.5. Программа all2all

Программа all2all предназначена для демонстрации способа, с помощью которого можно обеспечить взаимодействие внутри множества асинхронных (распределенных) процессов в соответствии с принципом "все со всеми". В определенном смысле, эта программа показывает, как можно реализовать на языке MC# глобальные (в терминах MPI, "широковещательные"(broadcast) ) операции передачи данных. Данный подход часто используется в программах, реализующих параллелизм по данным, когда отдельные процессы (процессоры) должны обмениваться сообщениями как со своими соседями, так и со всеми процессами, участвующими в вычислениях.

Ниже будет представлен вариант программы all2all с распределенными ( movable- ) процессами.

В этой программе, каждый распределенный процесс представляется методом Start объекта класса DistribProcess. Для взаимодействия между собой, каждый распределенный процесс создает объект класса BDChannel (Bidirectional channel), содержащий канал Send и обработчик Receive:


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



Каждый распределенный процесс (объект класса DistribProcess ) выполняет в данной программе следующую последовательность действий:

  1. Создает свой собственный объект класса BDChannel и отсылает его главному процессу.
  2. Принимает от главного процесса массив объектов класса BDChannel всех остальных процессов (включая свой собственный).
  3. Пользуясь этим массивом, посылает сообщение всем остальным процессам в группе.
  4. Принимает сообщения от всех процессов в группе.
  5. Посылает сигнал об окончании своей работы главному процессу.

Полный текст программы All2all приведен в приложении [ "Программирование на языке MC#" ].

Дмитрий Молокоедов
Дмитрий Молокоедов
Россия, Новосибирск, НГПУ, 2009
Паулус Шеетекела
Паулус Шеетекела
Россия, ТГТУ, 2010