Математические модели в виде
Пусть G есть
G=(V,R),
для которого набор вершин Vi,
0<=i<=n, задается множеством V, а список
дуг R. В общем случае дугам wj, 0<=j<=m (взвешенный
(рис 10.1) Пример взвешенного ориентированного графаИзвестны различные способы задания m<<n2 ) целесообразно использовать
для определения m~n2 ), может быть
эффективно обеспечено при помощи матрицы смежности:
A=(aij), 1<=i, j<=n,
ненулевые значения элементов которой соответствуют дугам
(рис 10.2) Матрица смежности для графа с рис. 10.1Как положительный момент такого способа представления
Далее мы рассмотрим способы параллельной реализации алгоритмов
на
Исходной информацией для задачи является взвешенный G=(V,R), содержащий n вершин (|V|=n), в котором каждому ребру i есть ребро в вершину j,
то из этого не следует наличие ребра из j в i. В случае если
вершины все же соединены взаимообратными ребрами, веса,
приписанные им, могут не совпадать. Рассмотрим задачу, в которой
для имеющегося G требуется найти минимальные длины путей
между каждой парой вершин
В качестве метода, решающего задачу поиска кратчайших путей
между всеми парами пунктов назначения, далее используется
Для поиска минимальных расстояний между всеми парами пунктов
назначения Флойд предложил алгоритм, сложность которого имеет
порядок n3. В общем виде данный алгоритм может быть представлен
следующим образом:
Алгоритм 10.1. Общая схема
// Алгоритм 10.1
// Последовательный алгоритм Флойда
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
A[i, j] = min(A[i, j], A[i, k] + A[k, j]);
(реализация операции выбора минимального значения min должна
учитывать способ указания в матрице смежности несуществующих дуг A изменяется, после завершения вычислений в матрице A
будет храниться требуемый результат – длины минимальных путей для
каждой пары вершин исходного
Дополнительная информация и доказательство правильности
Как следует из общей схемы A.
Покажем корректность такого способа организации параллелизма.
Для этого нужно доказать, что операции обновления значений
матрицы A на одной и той же итерации внешнего цикла k могут
выполняться независимо. Иными словами, следует показать, что на
итерации k не происходит изменения элементов Aik и Akj ни для
одной пары индексов (i, j). Рассмотрим выражение, по которому
происходит изменение элементов матрицы A:
Aij <- min (Aij, Aik + Akj).
Для i=k получим
Akj <- min (Akj, Akk + Akj),
но тогда значение Akj не изменится, т.к. Akk=0.
Для j=k выражение преобразуется к виду
Aik <- min (Aik, Aik + Akk),
что также показывает неизменность значений Aik. Как результат,
необходимые условия для организации параллельных вычислений
обеспечены, и, тем самым, в качестве базовой подзадачи может быть
использована операция обновления элементов матрицы A (для
указания подзадач будем применять индексы обновляемых в
подзадачах элементов).
Выполнение вычислений в подзадачах становится возможным только
тогда, когда каждая подзадача (i, j) содержит необходимые для
расчетов элементы Aij, Aik, Akj матрицы A. Для исключения
дублирования данных разместим в подзадаче (i, j) единственный
элемент Aij, тогда получение всех остальных необходимых значений
может быть обеспечено только при помощи передачи данных. Таким
образом, каждый элемент Akj строки k матрицы A должен быть
передан всем подзадачам (k, j), 1<=j<=n, а каждый элемент Aik
столбца k матрицы A должен быть передан всем подзадачам (i, k),
1<=i<=n,– см. рис. 10.3.
(рис 10.3) Информационная зависимость базовых подзадач (стрелками показаны направления обмена значениями на итерации k)
Как правило, число доступных процессоров p существенно меньше,
чем число базовых задач n2 (p<<n2). Возможный способ укрупнения
вычислений состоит в использовании ленточной схемы разбиения
матрицы A – такой подход соответствует объединению в рамках одной
базовой подзадачи вычислений, связанных с обновлением элементов
одной или нескольких строк ( горизонтальное разбиение) или
столбцов ( вертикальное разбиение) матрицы A. Эти два типа
разбиения практически равноправны – учитывая дополнительный
момент, что для алгоритмического языка C массивы располагаются по
строкам, будем рассматривать далее только разбиение матрицы A на
горизонтальные полосы.
Следует отметить, что при таком способе разбиения данных на
каждой итерации A. Для
оптимального выполнения подобной коммуникационной операции
топология сети должна обеспечивать эффективное представление
структуры сети передачи данных в виде гиперкуба или полного
Выполним анализ эффективности параллельного
Общая трудоемкость последовательного алгоритма, как уже
отмечалось ранее, имеет порядок сложности n3. Для параллельного
алгоритма на отдельной итерации каждый процессор выполняет
обновление элементов матрицы А. Всего в подзадачах n2/p таких
элементов, число итераций алгоритма равно n – таким образом,
показатели ускорения и эффективности параллельного
Следовательно, общий анализ сложности дает идеальные
показатели эффективности параллельных вычислений. Для уточнения
полученных соотношений введем в полученные выражения время
выполнения базовой операции выбора минимального значения и учтем
затраты на выполнение
Коммуникационная операция, выполняемая на каждой итерации А
всем процессорам вычислительной системы. Как уже показывалось
ранее, такая операция может быть выполнена за $$\lceil log_{2}p\rceil$$ шагов. С
учетом количества итераций w есть размер элемента матрицы в
байтах.
С учетом полученных соотношений общее время выполнения
параллельного
Представим возможный вариант параллельной реализации
1. Главная функция программы. Реализует логику работы алгоритма, последовательно вызывает необходимые подпрограммы.
// Программа 10.1. — Алгоритм Флойда
int ProcRank; // Ранг текущего процесса
int ProcNum; // Количество процессов
// Функция вычисления минимума
int Min(int A, int B) {
int Result = (A < B) ? A : B;
if((A < 0) (B >= 0)) Result = B;
if((B < 0) (A >= 0)) Result = A;
if((A < 0) (B < 0)) Result = -1;
return Result;
}
// Главная функция программы
int main(int argc, char* argv[]) {
int *pMatrix; // Матрица смежности
int Size; // Размер матрицы смежности
int *pProcRows; // Строки матрицы смежности текущего процесса
int RowNum; // Число строк для текущего процесса
MPI_Init(argc, argv);
MPI_Comm_size(MPI_COMM_WORLD, ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD, ProcRank);
// Инициализация данных
ProcessInitialization(pMatrix, pProcRows, Size, RowNum);
// Распределение данных между процессами
DataDistribution(pMatrix, pProcRows, Size, RowNum);
// Параллельный алгоритм Флойда
ParallelFloyd(pProcRows, Size, RowNum);
// Сбор результатов работы алгоритма
ResultCollection(pMatrix, pProcRows, Size, RowNum);
// Завершение вычислений процесса
ProcessTermination(pMatrix, pProcRows);
MPI_Finalize();
return 0;
}
Функция Min вычисляет меньшее из двух целых чисел, учитывая
применяемый способ задания несуществующих дуг в матрице смежности
(в рассматриваемой реализации для этого используется значение
-1).
Функция ProcessInitialization определяет исходные данные
решаемой задачи (количество вершин
Функция DataDistribution распределяет исходные данные между
процессами. Каждый процесс получает горизонтальную полосу матрицы
смежности.
Функция ResultCollection осуществляет сбор со всех процессов
горизонтальных полос результирующей матрицы кратчайших расстояний
между любыми парами вершин
Функция ProcessTermination выполняет необходимый вывод
результатов решения задачи и освобождает всю ранее выделенную
память для хранения данных.
Реализация всех перечисленных функций может быть выполнена по аналогии с ранее рассмотренными примерами и предоставляется читателю в качестве самостоятельного упражнения.
2. Функция ParallelFloyd. Данная функция осуществляет
итеративное изменение матрицы смежности в соответствии с
// Параллельный алгоритм Флойда
void ParallelFloyd(int *pProcRows, int Size, int RowNum) {
int *pRow = new int[Size];
int t1, t2;
for(int k = 0; k < Size; k++) {
// Распределение k-й строки среди процессов
RowDistribution(pProcRows, Size, RowNum, k, pRow);
// Обновление элементов матрицы смежности
for(int i = 0; i < RowNum; i++)
for(int j = 0; j < Size; j++)
if( (pProcRows[i * Size + k] != -1) (pRow [j]!= -1)){
t1 = pProcRows[i * Size + j];
t2 = pProcRows[i * Size + k] + pRow[j];
pProcRows[i * Size + j] = Min(t1, t2);
}
}
delete []pRow;
}
3. Функция RowDistribution. Данная функция рассылает k -ю
строку матрицы смежности всем процессам программы.
// Функция для рассылки строки всем процессам
void RowDistribution(int *pProcRows, int Size, int RowNum, int k,
int *pRow) {
int ProcRowRank; // Ранг процесса, которому принадлежит k-я строка
int ProcRowNum; // Номер k-й строки в полосе матрицы
// Нахождение ранга процесса – владельца k-й строки
int RestRows = Size;
int Ind = 0;
int Num = Size / ProcNum;
for(ProcRowRank = 1; ProcRowRank < ProcNum + 1; ProcRowRank ++) {
if(k < Ind + Num ) break;
RestRows -= Num;
Ind += Num;
Num = RestRows / (ProcNum - ProcRowRank);
}
ProcRowRank = ProcRowRank - 1;
ProcRowNum = k - Ind;
if(ProcRowRank == ProcRank)
// Копирование строки в массив pRow
copy(pProcRows[ProcRowNum * Size], pProcRows[(ProcRowNum + 1) *
Size], pRow);
// Распределение k-й строки между процессами
MPI_Bcast(pRow, Size, MPI_INT, ProcRowRank, MPI_COMM_WORLD);
}
Эксперименты проводились на вычислительном кластере
Нижегородского университета на базе процессоров Intel Xeon 4
Для оценки длительности $$\tau$$ базовой скалярной операции выбора
минимального значения проводилось решение задачи поиска всех
кратчайших путей при помощи последовательного алгоритма и
полученное таким образом время вычислений делилось на общее
количество выполненных операций – в результате для величины $$\tau$$
было получено значение 7,14 нсек. Эксперименты, выполненные для
определения параметров сети передачи данных, показали значения
латентности $$\alpha$$ и пропускной способности $$\beta$$ соответственно 130 мкс и
53,29 Мбайт/с. Все вычисления производились над числовыми
значениями типа int, размер которого на данной платформе равен 4
байта (следовательно, w=4 ).
Результаты вычислительных экспериментов приведены в таблице 10.1. Эксперименты выполнялись с использованием двух, четырех и восьми процессоров. Время указано в секундах.
| Кол-во вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| Время | Ускорение | Время | Ускорение | Время | Ускорение | ||
| 1000 | 8,037 | 4,152 | 1,936 | 2,067 | 3,888 | 0,941 | 8,544 |
| 2000 | 59,812 | 30,323 | 1,972 | 15,375 | 3,890 | 8,058 | 7,423 |
| 3000 | 197,111 | 99,264 | 1,986 | 50,232 | 3,924 | 25,643 | 7,687 |
| 4000 | 461,785 | 232,507 | 1,986 | 117,220 | 3,939 | 69,946 | 6,602 |
| 5000 | 884,622 | 443,747 | 1,994 | 224,441 | 3,941 | 128,078 | 6,907 |
(рис 10.4) Графики зависимости ускорения параллельного алгоритма Флойда от числа используемых процессоров при различном количестве вершин графаСравнение времени выполнения эксперимента $$T^*_p$$ и
теоретической оценки Tp из (10.3)
приведено в таблице 10.2 и на
рис. 10.5.
(рис 10.5) Графики экспериментально установленного времени работы параллельного алгоритма Флойда и теоретической оценки в зависимости от количества вершин графа при использовании двух процессоров| Количество вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| $$T_1^*$$ | $$T_2$$ | $$T_2^*$$ | $$T_4$$ | $$T_4^*$$ | $$T_8$$ | $$T_8^*$$ | |
| 1000 | 8,038 | 3,776 | 4,152 | 2,196 | 2,067 | 1,509 | 0,941 |
| 2000 | 59,812 | 29,123 | 30,323 | 15,405 | 15,375 | 8,826 | 8,058 |
| 3000 | 197,111 | 97,465 | 99,264 | 50,336 | 50,232 | 27,307 | 25,643 |
| 4000 | 461,785 | 230,220 | 232,507 | 117,701 | 117,220 | 62,306 | 69,946 |
| 5000 | 884,622 | 448,811 | 443,747 | 228,211 | 224,441 | 119,179 | 128,078 |
Охватывающим деревом (или остовом ) неориентированного G
называется подграф T G, который является деревом и содержит
все вершины из G. Определив вес подграфа для взвешенного (МОД) T будем понимать охватывающее дерево
минимального веса. Содержательная интерпретация задачи нахождения
МОД может состоять, например, в практическом примере построения
локальной сети персональных компьютеров с прокладыванием
соединительных линий связи минимальной длины. Пример взвешенного
неориентированного
(рис 10.6) Пример взвешенного неориентированного графа (а) и соответствующему ему минимально охватывающего дерева (б)Дадим общее описание алгоритма решения поставленной задачи, известного под названием метода Прима ( the Prim method ); более полная информация может быть получена, например, в [].
Алгоритм начинает работу с произвольной вершины VT есть множество вершин, уже включенных алгоритмом в МОД,
а величины di, 1<=i<=n, характеризуют дуги минимальной длины от
вершин, еще не включенных в дерево, до множества VT, т.е.$$\forall i \notin V_T \Rightarrow d_i = \min\{ w(i,u):u\in V_T,(i,u)\in R\}$$
(если для какой-либо вершины $$i\notin V_{T}$$ не существует ни одной дуги в VT, значение di устанавливается равным $$\infty$$ ). В начале работы
алгоритма выбирается корневая вершина МОД s и полагается VT={s},
ds=0.
Действия, выполняемые на каждой итерации
di для всех вершин, еще не включенных в состав МОД;t G, имеющая дугу минимального веса до множества $$V_{T}t:d_{t},\ i\notin V_{T}$$ ;t включается в VT.После выполнения n-1 итерации метода МОД будет сформировано. Вес этого дерева может быть получен при помощи выражения$$W_T = \sum_{i=1}^n d_i.$$
Трудоемкость нахождения МОД характеризуется квадратичной
зависимостью от числа вершин T1~n2.
Оценим возможности параллельного выполнения рассмотренного алгоритма нахождения минимально охватывающего дерева.
Итерации метода должны выполняться последовательно и, тем
самым, не могут быть распараллелены. С другой стороны,
выполняемые на каждой итерации алгоритма действия являются
независимыми и могут реализовываться одновременно. Так, например,
определение величин di может осуществляться для каждой вершины
Распределение данных между процессорами вычислительной системы
должно обеспечивать независимость перечисленных операций pj, 1<=j<=p, должен содержать:
k величин$$\Delta_j = \{d_{i_j +1},d_{i_j +2},\ldots,d_{i_j +k}\};$$
G из k соседних столбцов$$A_j=\{\alpha_{i_j +1},\alpha_{i_j +2},\ldots,\alpha_{i_j +k}\} (\alpha_s \text{ есть } s\text{-й столбец матрицы } A);$$
Vj и формируемого в процессе вычислений множества вершин VT.Как итог можем заключить, что базовой подзадачей в
параллельном Vj матрицы смежности A G.
С учетом выбора базовых подзадач общая схема параллельного
выполнения
t G, имеющая дугу минимального
веса до множества VT. Для выбора такой вершины необходимо
осуществить поиск минимума в наборах величин di, имеющихся на
каждом из процессоров, и выполнить сборку полученных значений на
одном из процессоров;di с учетом добавления новой вершины.Таким образом, в ходе параллельных вычислений между процессорами выполняются два типа информационных взаимодействий: сбор данных от всех процессоров на одном из процессоров и передача сообщений от одного процессора всем процессорам вычислительной системы.
По определению количество базовых подзадач всегда соответствует числу имеющихся процессоров, и, тем самым, проблема масштабирования для параллельного алгоритма не возникает.
Распределение подзадач между процессорами должно учитывать
характер выполняемых в
Общий анализ сложности параллельного
При этом следует отметить, что в ходе параллельных вычислений
идеальная балансировка вычислительной нагрузки процессоров может
быть нарушена. В зависимости от вида исходного G количество
выбранных вершин в охватывающем дереве на разных процессорах
может оказаться различным, и распределение вычислений между
процессорами станет неравномерным (вплоть до отсутствия
вычислительной нагрузки на отдельных процессорах). Однако такие
предельные ситуации нарушения балансировки в общем случае
возникают достаточно редко, а организация динамического
перераспределения вычислительной нагрузки между процессорами в
ходе вычислений является интересной, но одновременно и очень
сложной задачей.
Для уточнения полученных показателей эффективности
параллельных вычислений оценим более точно количество
вычислительных операций алгоритма и учтем затраты на выполнение
При выполнении вычислений на отдельной итерации параллельного Vj до охватывающего дерева и осуществляет
корректировку расстояний di после расширения МОД. Количество
выполняемых операций в каждой из этих вычислительных процедур
ограничивается сверху числом вершин, имеющихся на процессорах, т.е.
величиной $$\lceil n/p\rceil$$. Как результат, с учетом общего количества
итераций n время выполнения вычислительных операций параллельного
Операция сбора данных от всех процессоров на одном из
процессоров может быть произведена за $$\lceil log_{2}p\rceil$$ итераций, при этом
общая оценка длительности выполнения передачи данных определяется
выражением (более подробное рассмотрение данной коммуникационной
операции содержится в лекции 3):$$T_p^1(comm)=n(\alpha \log_2 p +3w(p-1)/ \beta),$$
где $$\alpha$$ – латентность сети передачи данных, $$\beta$$ – пропускная
способность сети, а w есть размер одного пересылаемого элемента
данных в байтах (коэффициент 3 в выражении соответствует числу
передаваемых значений между процессорами – длина минимальной дуги
и номера двух вершин, которые соединяются этой дугой).
Коммуникационная
С учетом всех полученных соотношений общее время выполнения
параллельного
Вычислительные эксперименты для оценки эффективности
параллельного
Для оценки длительности $$\tau$$ базовой скалярной операции
проводилось решение задачи нахождения минимального охватывающего
дерева при помощи последовательного алгоритма и полученное таким
образом время вычислений делилось на общее количество выполненных
операций – в результате подобных экспериментов для величины $$\tau$$
было получено значение 4,76 нсек. Все вычисления производились
над числовыми значениями типа int, размер которого на данной
платформе равен 4 байта (следовательно, w=4 ).
Результаты вычислительных экспериментов даны в таблице 10.3. Эксперименты проводились с использованием двух, четырех и восьми процессоров. Время указано в секундах.
| Кол-во вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| Время | Ускорение | Время | Ускорение | Время | Ускорение | ||
| 1000 | 0,044 | 0,248 | 0,176 | 0,932 | 0,047 | 1,574 | 0,028 |
| 2000 | 0,208 | 0,684 | 0,304 | 1,800 | 0,115 | 2,159 | 0,096 |
| 3000 | 0,485 | 1,403 | 0,346 | 2,214 | 0,219 | 3,195 | 0,152 |
| 4000 | 0,873 | 1,946 | 0,622 | 3,324 | 0,263 | 5,431 | 0,161 |
| 5000 | 1,432 | 2,665 | 0,736 | 2,933 | 0,488 | 4,119 | 0,348 |
| 6000 | 2,189 | 2,900 | 0,821 | 4,291 | 0,510 | 7,737 | 0,283 |
| 7000 | 3,042 | 3,236 | 0,940 | 6,327 | 0,481 | 8,825 | 0,345 |
| 8000 | 4,150 | 4,462 | 0,930 | 6,993 | 0,593 | 10,390 | 0,399 |
| 9000 | 5,622 | 5,834 | 0,964 | 7,475 | 0,752 | 10,764 | 0,522 |
| 10000 | 7,512 | 6,990 | 1,075 | 8,597 | 0,874 | 14,095 | 0,533 |
(рис 10.7) Графики зависимости ускорения параллельного алгоритма Прима от числа используемых процессоров при различном количестве вершин в моделиСравнение времени выполнения эксперимента $$T^*_p$$ и теоретической
оценки Tp из (10.8) приведено в таблице 10.4 и на рис. 10.8.
| Количество вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| $$T_1^*$$ | $$T_2$$ | $$T_2^*$$ | $$T_4$$ | $$T_4^*$$ | $$T_8$$ | $$T_8^*$$ | |
| 1000 | 0,044 | 0,405 | 0,248 | 0,804 | 0,932 | 1,205 | 1,574 |
| 2000 | 0,208 | 0,820 | 0,684 | 1,613 | 1,800 | 2,412 | 2,159 |
| 3000 | 0,485 | 1,245 | 1,403 | 2,426 | 2,214 | 3,622 | 3,195 |
| 4000 | 0,873 | 1,679 | 1,946 | 3,245 | 3,324 | 4,834 | 5,431 |
| 5000 | 1,432 | 2,122 | 2,665 | 4,068 | 2,933 | 6,048 | 4,119 |
| 6000 | 2,189 | 2,575 | 2,900 | 4,896 | 4,291 | 7,265 | 7,737 |
| 7000 | 3,042 | 3,038 | 3,236 | 5,728 | 6,327 | 8,484 | 8,825 |
| 8000 | 4,150 | 3,510 | 4,462 | 6,566 | 6,993 | 9,705 | 10,390 |
| 9000 | 5,622 | 3,991 | 5,834 | 7,408 | 7,475 | 10,929 | 10,764 |
| 10000 | 7,512 | 4,482 | 6,990 | 8,255 | 8,597 | 12,155 | 14,095 |
(рис 10.8) Графики экспериментально установленного времени работы параллельного алгоритма Прима и теоретической оценки в зависимости от количества вершин в модели при использовании двух процессоровКак можно заметить из табл. 10.4 и рис. 10.8, теоретические
оценки определяют время выполнения
(рис 10.9) Пример разделения нерегулярной сетиОчевидно, что такие задачи разделения сети между процессорами
могут быть сведены к
Для представления сети в виде
(рис 10.10) Пример графа, моделирующего структуру сети на рис. 10.9Дополнительная информация по проблеме разделения
Пусть дан взвешенный неориентированный G=(V,E), каждой
вершине $$\nu \in V$$ и каждому ребру $$e\in E$$ которого приписан вес.
Следует отметить возможную противоречивость указанных
критериев разбиения
Далее для простоты изложения учебного материала будем полагать
веса вершин и ребер
Для решения задачи разбиения k частей необходимо log2k уровней рекурсии и выполнение k-1 деления пополам. В случае когда требуемое количество
разбиений k не является степенью двойки, каждое деление пополам
необходимо осуществлять в соответствующем соотношении.
Поясним схему работы метода деления пополам на примере
разделения
(рис 10.11) Пример разбиения графа на 5 частей методом рекурсивного деления пополам
Геометрические методы (см., например, [, , , , , ,
, ]) выполняют разбиение сетей, основываясь исключительно на
координатной информации об узлах сети. Так как эти методы не
принимают во внимание информацию о связности элементов сети, они
не могут явно привести к минимизации суммарного веса граничных
ребер (в терминах
Обычно геометрические методы не требуют большого объема вычислений, однако качество их разбиения уступает методам, принимающим во внимание связность элементов сети.
Покоординатное разбиение ( the coordinate nested dissection ) – это метод, основанный на рекурсивном делении пополам сети по наиболее длинной стороне. В качестве иллюстрации на рис. 10.12 показан пример сети, при разделении которой именно такой способ разбиения дает существенно меньшее количество информационных связей между разделенными частями, по сравнению со случаем, когда сеть делится по меньшей (вертикальной) стороне.
(рис 10.12) Пример разделения сети графическим методом по наибольшей размерности (граница раздела показана жирной линией)Общая схема выполнения метода состоит в следующем. Сначала вычисляются центры масс элементов сети. Полученные точки проектируются на ось, соответствующую наибольшей стороне разделяемой сети. Таким образом мы получаем упорядоченный список всех элементов сети. Делением списка пополам (возможно, в нужной пропорции) мы получаем требуемую бисекцию. Аналогичным способом полученные фрагменты разбиения рекурсивно делятся на нужное число частей.
Метод координатного вложенного разбиения работает очень быстро и требует небольшого количества оперативной памяти. Однако получаемое разбиение уступает по качеству более сложным и вычислительно трудоемким методам. Кроме того, в случае сложной структуры сети алгоритм может получать разбиение с несвязанными подсетями.
Предыдущая схема могла производить разбиение сети только по линии, перпендикулярной одной из координатных осей. Во многих случаях такое ограничение оказывается критичным для построения качественного разбиения. Достаточно повернуть сеть на рис. 10.12 под острым углом к координатным осям (см. рис. 10.13), чтобы убедиться в этом. Для минимизации границы между подсетями желательна возможность проведения линии разделения с любым требуемым углом поворота. Возможный способ определения угла поворота, используемый в рекурсивном инерционном методе деления пополам ( the recursive inertial bisection ), состоит в использовании главной инерционной оси (см., например, []), считая элементы сети точечными массами. Линия бисекции, ортогональная полученной оси, как правило, дает границу наименьшей длины.
(рис 10.13) Пример разделения сети методом рекурсивной инерционной бисекции. Стрелкой показана главная инерционная ось
Одним из недостатков предыдущих графических методов является то, что при каждой бисекции эти методы учитывают только одну размерность. Таким образом, схемы, учитывающие больше размерностей, могут обеспечить лучшее разбиение.
Один из таких методов упорядочивает элементы в соответствии с позициями центров их масс вдоль кривых Пеано. Кривые Пеано – это кривые, полностью заполняющие области больших размерностей (например, квадрат или куб). Применение таких кривых обеспечивает близость точек фигуры, которые соответствуют точкам, близким на кривой. После получения списка элементов сети, упорядоченного в зависимости от расположения на кривой, достаточно разделить список на необходимое число частей в соответствии с установленным порядком. Получаемый в результате такого подхода метод носит в литературе наименование алгоритма деления сети с использованием кривых Пеано ( the space-filling curve technique ). Подробнее о методе можно прочитать в работах [, , ].
(рис 10.14) Пример разделения сети на 3 части с использованием кривых Пеано
В отличие от геометрических методов, комбинаторные алгоритмы
(см., например, [, ]) обычно оперируют не с сетью, а с
С самых общих позиций понятно, что при разделении
Общая схема алгоритма может быть описана при помощи следующего набора правил.
Алгоритм 10.2. Общая схема выполнения алгоритма деления
Iteration = 0.Iteration произвольной вершине Iteration номера Iteration + 1.Iteration = Iteration + 1.Для минимизации информационных зависимостей имеет смысл в
качестве начальной выбирать граничную вершину. Поиск такой
вершины можно осуществить методом, близким к рассмотренной схеме.
Так, перенумеровав вершины
Пример работы алгоритма приведен на рис. 10.15. Цифрами показаны номера, которые получили вершины в процессе разделения. Сплошной линией показана граница, разделяющая 2 подграфа. Также на рисунке показано лучшее решение (пунктирная линия). Очевидно, что полученное алгоритмом разбиение далеко от оптимального, так как в приведенном примере есть решение только с тремя пересеченными ребрами вместо пяти.
(рис 10.15) Пример работы алгоритма деления графов с учетом связности
В алгоритме Кернигана – Лина ( the Kernighan – Lin algorithm )
используется несколько иной подход для решения
Общая схема одной итерации алгоритма Кернигана – Лина может быть представлена следующим образом.
Алгоритм 10.3. Общая схема алгоритма Кернигана – Лина
Поясним дополнительно, что на шаге 2 итерации алгоритма
перестановка вершин каждой очередной пары осуществляется для
одного и того же разбиения
(рис 10.16) Пример перестановки двух вершин (выделены серым) в методе Кернигана – Лина
Рассмотренные алгоритмы разбиения
| Алгоритмы | Необходимость координатной информации | Точность | Время выполнения | Возможности для распараллеливания | |
|---|---|---|---|---|---|
| Покоординатное разбиение | Да | $$ullet$$ | $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ | |
| Рекурсивный инерционный метод деления пополам | Да | $$ullet$$ $$ullet$$ | $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ | |
| Деление с учетом связности | Нет | $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | |
| Алгоритм Кернигана - Лина | 1 итерация | Нет | $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | $$ullet$$ |
| 10 итераций | Нет | $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | |
| 50 итераций | Нет | $$ullet$$ $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ $$ullet$$ | |
Столбец "Необходимость координатной информации"
отмечает использование алгоритмом координатной информации об
элементах сети или вершинах
Столбец "Точность" дает качественную характеристику
величины приближения получаемых алгоритмом решений к оптимальным
вариантам разбиения
Столбец "Время выполнения" показывает относительное время, затрачиваемое различными алгоритмами разбиения. Каждый дополнительный закрашенный кружок соответствует увеличению времени разбиения примерно в 10 раз.
Столбец "Возможности для распараллеливания" характеризует свойства алгоритмов для параллельного выполнения. Алгоритм Кернигана – Лина при выполнении только одной итерации почти не поддается распараллеливанию. Этот же алгоритм при большем количестве итераций, а также метод деления с учетом связности могут быть распараллелены со средней эффективностью. Алгоритм покоординатного разбиения и рекурсивный инерционный метод деления пополам обладают высокими показателями для распараллеливания.
В лекции рассмотрен ряд алгоритмов для решения типовых задач
обработки
В подразделе 10.1 представлен
В подразделе 10.2 рассматривается
Рассматриваемая в подразделе 10.3 задача оптимального
разделения
Дополнительная информация по алгоритмам Флойда и Прима может быть получена, например, в [].
Подробное рассмотрение вопросов, связанных с проблемой
разделения
Параллельные алгоритмы разделения
Математические модели в виде
Пусть G есть
G=(V,R),
для которого набор вершин Vi,
0<=i<=n, задается множеством V, а список
дуг R. В общем случае дугам wj, 0<=j<=m (взвешенный
(рис 10.1) Пример взвешенного ориентированного графаИзвестны различные способы задания m<<n2 ) целесообразно использовать
для определения m~n2 ), может быть
эффективно обеспечено при помощи матрицы смежности:
A=(aij), 1<=i, j<=n,
ненулевые значения элементов которой соответствуют дугам
(рис 10.2) Матрица смежности для графа с рис. 10.1Как положительный момент такого способа представления
Далее мы рассмотрим способы параллельной реализации алгоритмов
на
Исходной информацией для задачи является взвешенный G=(V,R), содержащий n вершин (|V|=n), в котором каждому ребру i есть ребро в вершину j,
то из этого не следует наличие ребра из j в i. В случае если
вершины все же соединены взаимообратными ребрами, веса,
приписанные им, могут не совпадать. Рассмотрим задачу, в которой
для имеющегося G требуется найти минимальные длины путей
между каждой парой вершин
В качестве метода, решающего задачу поиска кратчайших путей
между всеми парами пунктов назначения, далее используется
Для поиска минимальных расстояний между всеми парами пунктов
назначения Флойд предложил алгоритм, сложность которого имеет
порядок n3. В общем виде данный алгоритм может быть представлен
следующим образом:
Алгоритм 10.1. Общая схема
// Алгоритм 10.1
// Последовательный алгоритм Флойда
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
A[i, j] = min(A[i, j], A[i, k] + A[k, j]);
(реализация операции выбора минимального значения min должна
учитывать способ указания в матрице смежности несуществующих дуг A изменяется, после завершения вычислений в матрице A
будет храниться требуемый результат – длины минимальных путей для
каждой пары вершин исходного
Дополнительная информация и доказательство правильности
Как следует из общей схемы A.
Покажем корректность такого способа организации параллелизма.
Для этого нужно доказать, что операции обновления значений
матрицы A на одной и той же итерации внешнего цикла k могут
выполняться независимо. Иными словами, следует показать, что на
итерации k не происходит изменения элементов Aik и Akj ни для
одной пары индексов (i, j). Рассмотрим выражение, по которому
происходит изменение элементов матрицы A:
Aij <- min (Aij, Aik + Akj).
Для i=k получим
Akj <- min (Akj, Akk + Akj),
но тогда значение Akj не изменится, т.к. Akk=0.
Для j=k выражение преобразуется к виду
Aik <- min (Aik, Aik + Akk),
что также показывает неизменность значений Aik. Как результат,
необходимые условия для организации параллельных вычислений
обеспечены, и, тем самым, в качестве базовой подзадачи может быть
использована операция обновления элементов матрицы A (для
указания подзадач будем применять индексы обновляемых в
подзадачах элементов).
Выполнение вычислений в подзадачах становится возможным только
тогда, когда каждая подзадача (i, j) содержит необходимые для
расчетов элементы Aij, Aik, Akj матрицы A. Для исключения
дублирования данных разместим в подзадаче (i, j) единственный
элемент Aij, тогда получение всех остальных необходимых значений
может быть обеспечено только при помощи передачи данных. Таким
образом, каждый элемент Akj строки k матрицы A должен быть
передан всем подзадачам (k, j), 1<=j<=n, а каждый элемент Aik
столбца k матрицы A должен быть передан всем подзадачам (i, k),
1<=i<=n,– см. рис. 10.3.
(рис 10.3) Информационная зависимость базовых подзадач (стрелками показаны направления обмена значениями на итерации k)
Как правило, число доступных процессоров p существенно меньше,
чем число базовых задач n2 (p<<n2). Возможный способ укрупнения
вычислений состоит в использовании ленточной схемы разбиения
матрицы A – такой подход соответствует объединению в рамках одной
базовой подзадачи вычислений, связанных с обновлением элементов
одной или нескольких строк ( горизонтальное разбиение) или
столбцов ( вертикальное разбиение) матрицы A. Эти два типа
разбиения практически равноправны – учитывая дополнительный
момент, что для алгоритмического языка C массивы располагаются по
строкам, будем рассматривать далее только разбиение матрицы A на
горизонтальные полосы.
Следует отметить, что при таком способе разбиения данных на
каждой итерации A. Для
оптимального выполнения подобной коммуникационной операции
топология сети должна обеспечивать эффективное представление
структуры сети передачи данных в виде гиперкуба или полного
Выполним анализ эффективности параллельного
Общая трудоемкость последовательного алгоритма, как уже
отмечалось ранее, имеет порядок сложности n3. Для параллельного
алгоритма на отдельной итерации каждый процессор выполняет
обновление элементов матрицы А. Всего в подзадачах n2/p таких
элементов, число итераций алгоритма равно n – таким образом,
показатели ускорения и эффективности параллельного
Следовательно, общий анализ сложности дает идеальные
показатели эффективности параллельных вычислений. Для уточнения
полученных соотношений введем в полученные выражения время
выполнения базовой операции выбора минимального значения и учтем
затраты на выполнение
Коммуникационная операция, выполняемая на каждой итерации А
всем процессорам вычислительной системы. Как уже показывалось
ранее, такая операция может быть выполнена за $$\lceil log_{2}p\rceil$$ шагов. С
учетом количества итераций w есть размер элемента матрицы в
байтах.
С учетом полученных соотношений общее время выполнения
параллельного
Представим возможный вариант параллельной реализации
1. Главная функция программы. Реализует логику работы алгоритма, последовательно вызывает необходимые подпрограммы.
// Программа 10.1. — Алгоритм Флойда
int ProcRank; // Ранг текущего процесса
int ProcNum; // Количество процессов
// Функция вычисления минимума
int Min(int A, int B) {
int Result = (A < B) ? A : B;
if((A < 0) (B >= 0)) Result = B;
if((B < 0) (A >= 0)) Result = A;
if((A < 0) (B < 0)) Result = -1;
return Result;
}
// Главная функция программы
int main(int argc, char* argv[]) {
int *pMatrix; // Матрица смежности
int Size; // Размер матрицы смежности
int *pProcRows; // Строки матрицы смежности текущего процесса
int RowNum; // Число строк для текущего процесса
MPI_Init(argc, argv);
MPI_Comm_size(MPI_COMM_WORLD, ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD, ProcRank);
// Инициализация данных
ProcessInitialization(pMatrix, pProcRows, Size, RowNum);
// Распределение данных между процессами
DataDistribution(pMatrix, pProcRows, Size, RowNum);
// Параллельный алгоритм Флойда
ParallelFloyd(pProcRows, Size, RowNum);
// Сбор результатов работы алгоритма
ResultCollection(pMatrix, pProcRows, Size, RowNum);
// Завершение вычислений процесса
ProcessTermination(pMatrix, pProcRows);
MPI_Finalize();
return 0;
}
Функция Min вычисляет меньшее из двух целых чисел, учитывая
применяемый способ задания несуществующих дуг в матрице смежности
(в рассматриваемой реализации для этого используется значение
-1).
Функция ProcessInitialization определяет исходные данные
решаемой задачи (количество вершин
Функция DataDistribution распределяет исходные данные между
процессами. Каждый процесс получает горизонтальную полосу матрицы
смежности.
Функция ResultCollection осуществляет сбор со всех процессов
горизонтальных полос результирующей матрицы кратчайших расстояний
между любыми парами вершин
Функция ProcessTermination выполняет необходимый вывод
результатов решения задачи и освобождает всю ранее выделенную
память для хранения данных.
Реализация всех перечисленных функций может быть выполнена по аналогии с ранее рассмотренными примерами и предоставляется читателю в качестве самостоятельного упражнения.
2. Функция ParallelFloyd. Данная функция осуществляет
итеративное изменение матрицы смежности в соответствии с
// Параллельный алгоритм Флойда
void ParallelFloyd(int *pProcRows, int Size, int RowNum) {
int *pRow = new int[Size];
int t1, t2;
for(int k = 0; k < Size; k++) {
// Распределение k-й строки среди процессов
RowDistribution(pProcRows, Size, RowNum, k, pRow);
// Обновление элементов матрицы смежности
for(int i = 0; i < RowNum; i++)
for(int j = 0; j < Size; j++)
if( (pProcRows[i * Size + k] != -1) (pRow [j]!= -1)){
t1 = pProcRows[i * Size + j];
t2 = pProcRows[i * Size + k] + pRow[j];
pProcRows[i * Size + j] = Min(t1, t2);
}
}
delete []pRow;
}
3. Функция RowDistribution. Данная функция рассылает k -ю
строку матрицы смежности всем процессам программы.
// Функция для рассылки строки всем процессам
void RowDistribution(int *pProcRows, int Size, int RowNum, int k,
int *pRow) {
int ProcRowRank; // Ранг процесса, которому принадлежит k-я строка
int ProcRowNum; // Номер k-й строки в полосе матрицы
// Нахождение ранга процесса – владельца k-й строки
int RestRows = Size;
int Ind = 0;
int Num = Size / ProcNum;
for(ProcRowRank = 1; ProcRowRank < ProcNum + 1; ProcRowRank ++) {
if(k < Ind + Num ) break;
RestRows -= Num;
Ind += Num;
Num = RestRows / (ProcNum - ProcRowRank);
}
ProcRowRank = ProcRowRank - 1;
ProcRowNum = k - Ind;
if(ProcRowRank == ProcRank)
// Копирование строки в массив pRow
copy(pProcRows[ProcRowNum * Size], pProcRows[(ProcRowNum + 1) *
Size], pRow);
// Распределение k-й строки между процессами
MPI_Bcast(pRow, Size, MPI_INT, ProcRowRank, MPI_COMM_WORLD);
}
Эксперименты проводились на вычислительном кластере
Нижегородского университета на базе процессоров Intel Xeon 4
Для оценки длительности $$\tau$$ базовой скалярной операции выбора
минимального значения проводилось решение задачи поиска всех
кратчайших путей при помощи последовательного алгоритма и
полученное таким образом время вычислений делилось на общее
количество выполненных операций – в результате для величины $$\tau$$
было получено значение 7,14 нсек. Эксперименты, выполненные для
определения параметров сети передачи данных, показали значения
латентности $$\alpha$$ и пропускной способности $$\beta$$ соответственно 130 мкс и
53,29 Мбайт/с. Все вычисления производились над числовыми
значениями типа int, размер которого на данной платформе равен 4
байта (следовательно, w=4 ).
Результаты вычислительных экспериментов приведены в таблице 10.1. Эксперименты выполнялись с использованием двух, четырех и восьми процессоров. Время указано в секундах.
| Кол-во вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| Время | Ускорение | Время | Ускорение | Время | Ускорение | ||
| 1000 | 8,037 | 4,152 | 1,936 | 2,067 | 3,888 | 0,941 | 8,544 |
| 2000 | 59,812 | 30,323 | 1,972 | 15,375 | 3,890 | 8,058 | 7,423 |
| 3000 | 197,111 | 99,264 | 1,986 | 50,232 | 3,924 | 25,643 | 7,687 |
| 4000 | 461,785 | 232,507 | 1,986 | 117,220 | 3,939 | 69,946 | 6,602 |
| 5000 | 884,622 | 443,747 | 1,994 | 224,441 | 3,941 | 128,078 | 6,907 |
(рис 10.4) Графики зависимости ускорения параллельного алгоритма Флойда от числа используемых процессоров при различном количестве вершин графаСравнение времени выполнения эксперимента $$T^*_p$$ и
теоретической оценки Tp из (10.3)
приведено в таблице 10.2 и на
рис. 10.5.
(рис 10.5) Графики экспериментально установленного времени работы параллельного алгоритма Флойда и теоретической оценки в зависимости от количества вершин графа при использовании двух процессоров| Количество вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| $$T_1^*$$ | $$T_2$$ | $$T_2^*$$ | $$T_4$$ | $$T_4^*$$ | $$T_8$$ | $$T_8^*$$ | |
| 1000 | 8,038 | 3,776 | 4,152 | 2,196 | 2,067 | 1,509 | 0,941 |
| 2000 | 59,812 | 29,123 | 30,323 | 15,405 | 15,375 | 8,826 | 8,058 |
| 3000 | 197,111 | 97,465 | 99,264 | 50,336 | 50,232 | 27,307 | 25,643 |
| 4000 | 461,785 | 230,220 | 232,507 | 117,701 | 117,220 | 62,306 | 69,946 |
| 5000 | 884,622 | 448,811 | 443,747 | 228,211 | 224,441 | 119,179 | 128,078 |
Охватывающим деревом (или остовом ) неориентированного G
называется подграф T G, который является деревом и содержит
все вершины из G. Определив вес подграфа для взвешенного (МОД) T будем понимать охватывающее дерево
минимального веса. Содержательная интерпретация задачи нахождения
МОД может состоять, например, в практическом примере построения
локальной сети персональных компьютеров с прокладыванием
соединительных линий связи минимальной длины. Пример взвешенного
неориентированного
(рис 10.6) Пример взвешенного неориентированного графа (а) и соответствующему ему минимально охватывающего дерева (б)Дадим общее описание алгоритма решения поставленной задачи, известного под названием метода Прима ( the Prim method ); более полная информация может быть получена, например, в [].
Алгоритм начинает работу с произвольной вершины VT есть множество вершин, уже включенных алгоритмом в МОД,
а величины di, 1<=i<=n, характеризуют дуги минимальной длины от
вершин, еще не включенных в дерево, до множества VT, т.е.$$\forall i \notin V_T \Rightarrow d_i = \min\{ w(i,u):u\in V_T,(i,u)\in R\}$$
(если для какой-либо вершины $$i\notin V_{T}$$ не существует ни одной дуги в VT, значение di устанавливается равным $$\infty$$ ). В начале работы
алгоритма выбирается корневая вершина МОД s и полагается VT={s},
ds=0.
Действия, выполняемые на каждой итерации
di для всех вершин, еще не включенных в состав МОД;t G, имеющая дугу минимального веса до множества $$V_{T}t:d_{t},\ i\notin V_{T}$$ ;t включается в VT.После выполнения n-1 итерации метода МОД будет сформировано. Вес этого дерева может быть получен при помощи выражения$$W_T = \sum_{i=1}^n d_i.$$
Трудоемкость нахождения МОД характеризуется квадратичной
зависимостью от числа вершин T1~n2.
Оценим возможности параллельного выполнения рассмотренного алгоритма нахождения минимально охватывающего дерева.
Итерации метода должны выполняться последовательно и, тем
самым, не могут быть распараллелены. С другой стороны,
выполняемые на каждой итерации алгоритма действия являются
независимыми и могут реализовываться одновременно. Так, например,
определение величин di может осуществляться для каждой вершины
Распределение данных между процессорами вычислительной системы
должно обеспечивать независимость перечисленных операций pj, 1<=j<=p, должен содержать:
k величин$$\Delta_j = \{d_{i_j +1},d_{i_j +2},\ldots,d_{i_j +k}\};$$
G из k соседних столбцов$$A_j=\{\alpha_{i_j +1},\alpha_{i_j +2},\ldots,\alpha_{i_j +k}\} (\alpha_s \text{ есть } s\text{-й столбец матрицы } A);$$
Vj и формируемого в процессе вычислений множества вершин VT.Как итог можем заключить, что базовой подзадачей в
параллельном Vj матрицы смежности A G.
С учетом выбора базовых подзадач общая схема параллельного
выполнения
t G, имеющая дугу минимального
веса до множества VT. Для выбора такой вершины необходимо
осуществить поиск минимума в наборах величин di, имеющихся на
каждом из процессоров, и выполнить сборку полученных значений на
одном из процессоров;di с учетом добавления новой вершины.Таким образом, в ходе параллельных вычислений между процессорами выполняются два типа информационных взаимодействий: сбор данных от всех процессоров на одном из процессоров и передача сообщений от одного процессора всем процессорам вычислительной системы.
По определению количество базовых подзадач всегда соответствует числу имеющихся процессоров, и, тем самым, проблема масштабирования для параллельного алгоритма не возникает.
Распределение подзадач между процессорами должно учитывать
характер выполняемых в
Общий анализ сложности параллельного
При этом следует отметить, что в ходе параллельных вычислений
идеальная балансировка вычислительной нагрузки процессоров может
быть нарушена. В зависимости от вида исходного G количество
выбранных вершин в охватывающем дереве на разных процессорах
может оказаться различным, и распределение вычислений между
процессорами станет неравномерным (вплоть до отсутствия
вычислительной нагрузки на отдельных процессорах). Однако такие
предельные ситуации нарушения балансировки в общем случае
возникают достаточно редко, а организация динамического
перераспределения вычислительной нагрузки между процессорами в
ходе вычислений является интересной, но одновременно и очень
сложной задачей.
Для уточнения полученных показателей эффективности
параллельных вычислений оценим более точно количество
вычислительных операций алгоритма и учтем затраты на выполнение
При выполнении вычислений на отдельной итерации параллельного Vj до охватывающего дерева и осуществляет
корректировку расстояний di после расширения МОД. Количество
выполняемых операций в каждой из этих вычислительных процедур
ограничивается сверху числом вершин, имеющихся на процессорах, т.е.
величиной $$\lceil n/p\rceil$$. Как результат, с учетом общего количества
итераций n время выполнения вычислительных операций параллельного
Операция сбора данных от всех процессоров на одном из
процессоров может быть произведена за $$\lceil log_{2}p\rceil$$ итераций, при этом
общая оценка длительности выполнения передачи данных определяется
выражением (более подробное рассмотрение данной коммуникационной
операции содержится в лекции 3):$$T_p^1(comm)=n(\alpha \log_2 p +3w(p-1)/ \beta),$$
где $$\alpha$$ – латентность сети передачи данных, $$\beta$$ – пропускная
способность сети, а w есть размер одного пересылаемого элемента
данных в байтах (коэффициент 3 в выражении соответствует числу
передаваемых значений между процессорами – длина минимальной дуги
и номера двух вершин, которые соединяются этой дугой).
Коммуникационная
С учетом всех полученных соотношений общее время выполнения
параллельного
Вычислительные эксперименты для оценки эффективности
параллельного
Для оценки длительности $$\tau$$ базовой скалярной операции
проводилось решение задачи нахождения минимального охватывающего
дерева при помощи последовательного алгоритма и полученное таким
образом время вычислений делилось на общее количество выполненных
операций – в результате подобных экспериментов для величины $$\tau$$
было получено значение 4,76 нсек. Все вычисления производились
над числовыми значениями типа int, размер которого на данной
платформе равен 4 байта (следовательно, w=4 ).
Результаты вычислительных экспериментов даны в таблице 10.3. Эксперименты проводились с использованием двух, четырех и восьми процессоров. Время указано в секундах.
| Кол-во вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| Время | Ускорение | Время | Ускорение | Время | Ускорение | ||
| 1000 | 0,044 | 0,248 | 0,176 | 0,932 | 0,047 | 1,574 | 0,028 |
| 2000 | 0,208 | 0,684 | 0,304 | 1,800 | 0,115 | 2,159 | 0,096 |
| 3000 | 0,485 | 1,403 | 0,346 | 2,214 | 0,219 | 3,195 | 0,152 |
| 4000 | 0,873 | 1,946 | 0,622 | 3,324 | 0,263 | 5,431 | 0,161 |
| 5000 | 1,432 | 2,665 | 0,736 | 2,933 | 0,488 | 4,119 | 0,348 |
| 6000 | 2,189 | 2,900 | 0,821 | 4,291 | 0,510 | 7,737 | 0,283 |
| 7000 | 3,042 | 3,236 | 0,940 | 6,327 | 0,481 | 8,825 | 0,345 |
| 8000 | 4,150 | 4,462 | 0,930 | 6,993 | 0,593 | 10,390 | 0,399 |
| 9000 | 5,622 | 5,834 | 0,964 | 7,475 | 0,752 | 10,764 | 0,522 |
| 10000 | 7,512 | 6,990 | 1,075 | 8,597 | 0,874 | 14,095 | 0,533 |
(рис 10.7) Графики зависимости ускорения параллельного алгоритма Прима от числа используемых процессоров при различном количестве вершин в моделиСравнение времени выполнения эксперимента $$T^*_p$$ и теоретической
оценки Tp из (10.8) приведено в таблице 10.4 и на рис. 10.8.
| Количество вершин | Последовательный алгоритм | Параллельный алгоритм | |||||
|---|---|---|---|---|---|---|---|
| 2 процессора | 4 процессора | 8 процессоров | |||||
| $$T_1^*$$ | $$T_2$$ | $$T_2^*$$ | $$T_4$$ | $$T_4^*$$ | $$T_8$$ | $$T_8^*$$ | |
| 1000 | 0,044 | 0,405 | 0,248 | 0,804 | 0,932 | 1,205 | 1,574 |
| 2000 | 0,208 | 0,820 | 0,684 | 1,613 | 1,800 | 2,412 | 2,159 |
| 3000 | 0,485 | 1,245 | 1,403 | 2,426 | 2,214 | 3,622 | 3,195 |
| 4000 | 0,873 | 1,679 | 1,946 | 3,245 | 3,324 | 4,834 | 5,431 |
| 5000 | 1,432 | 2,122 | 2,665 | 4,068 | 2,933 | 6,048 | 4,119 |
| 6000 | 2,189 | 2,575 | 2,900 | 4,896 | 4,291 | 7,265 | 7,737 |
| 7000 | 3,042 | 3,038 | 3,236 | 5,728 | 6,327 | 8,484 | 8,825 |
| 8000 | 4,150 | 3,510 | 4,462 | 6,566 | 6,993 | 9,705 | 10,390 |
| 9000 | 5,622 | 3,991 | 5,834 | 7,408 | 7,475 | 10,929 | 10,764 |
| 10000 | 7,512 | 4,482 | 6,990 | 8,255 | 8,597 | 12,155 | 14,095 |
(рис 10.8) Графики экспериментально установленного времени работы параллельного алгоритма Прима и теоретической оценки в зависимости от количества вершин в модели при использовании двух процессоровКак можно заметить из табл. 10.4 и рис. 10.8, теоретические
оценки определяют время выполнения
(рис 10.9) Пример разделения нерегулярной сетиОчевидно, что такие задачи разделения сети между процессорами
могут быть сведены к
Для представления сети в виде
(рис 10.10) Пример графа, моделирующего структуру сети на рис. 10.9Дополнительная информация по проблеме разделения
Пусть дан взвешенный неориентированный G=(V,E), каждой
вершине $$\nu \in V$$ и каждому ребру $$e\in E$$ которого приписан вес.
Следует отметить возможную противоречивость указанных
критериев разбиения
Далее для простоты изложения учебного материала будем полагать
веса вершин и ребер
Для решения задачи разбиения k частей необходимо log2k уровней рекурсии и выполнение k-1 деления пополам. В случае когда требуемое количество
разбиений k не является степенью двойки, каждое деление пополам
необходимо осуществлять в соответствующем соотношении.
Поясним схему работы метода деления пополам на примере
разделения
(рис 10.11) Пример разбиения графа на 5 частей методом рекурсивного деления пополам
Геометрические методы (см., например, [, , , , , ,
, ]) выполняют разбиение сетей, основываясь исключительно на
координатной информации об узлах сети. Так как эти методы не
принимают во внимание информацию о связности элементов сети, они
не могут явно привести к минимизации суммарного веса граничных
ребер (в терминах
Обычно геометрические методы не требуют большого объема вычислений, однако качество их разбиения уступает методам, принимающим во внимание связность элементов сети.
Покоординатное разбиение ( the coordinate nested dissection ) – это метод, основанный на рекурсивном делении пополам сети по наиболее длинной стороне. В качестве иллюстрации на рис. 10.12 показан пример сети, при разделении которой именно такой способ разбиения дает существенно меньшее количество информационных связей между разделенными частями, по сравнению со случаем, когда сеть делится по меньшей (вертикальной) стороне.
(рис 10.12) Пример разделения сети графическим методом по наибольшей размерности (граница раздела показана жирной линией)Общая схема выполнения метода состоит в следующем. Сначала вычисляются центры масс элементов сети. Полученные точки проектируются на ось, соответствующую наибольшей стороне разделяемой сети. Таким образом мы получаем упорядоченный список всех элементов сети. Делением списка пополам (возможно, в нужной пропорции) мы получаем требуемую бисекцию. Аналогичным способом полученные фрагменты разбиения рекурсивно делятся на нужное число частей.
Метод координатного вложенного разбиения работает очень быстро и требует небольшого количества оперативной памяти. Однако получаемое разбиение уступает по качеству более сложным и вычислительно трудоемким методам. Кроме того, в случае сложной структуры сети алгоритм может получать разбиение с несвязанными подсетями.
Предыдущая схема могла производить разбиение сети только по линии, перпендикулярной одной из координатных осей. Во многих случаях такое ограничение оказывается критичным для построения качественного разбиения. Достаточно повернуть сеть на рис. 10.12 под острым углом к координатным осям (см. рис. 10.13), чтобы убедиться в этом. Для минимизации границы между подсетями желательна возможность проведения линии разделения с любым требуемым углом поворота. Возможный способ определения угла поворота, используемый в рекурсивном инерционном методе деления пополам ( the recursive inertial bisection ), состоит в использовании главной инерционной оси (см., например, []), считая элементы сети точечными массами. Линия бисекции, ортогональная полученной оси, как правило, дает границу наименьшей длины.
(рис 10.13) Пример разделения сети методом рекурсивной инерционной бисекции. Стрелкой показана главная инерционная ось
Одним из недостатков предыдущих графических методов является то, что при каждой бисекции эти методы учитывают только одну размерность. Таким образом, схемы, учитывающие больше размерностей, могут обеспечить лучшее разбиение.
Один из таких методов упорядочивает элементы в соответствии с позициями центров их масс вдоль кривых Пеано. Кривые Пеано – это кривые, полностью заполняющие области больших размерностей (например, квадрат или куб). Применение таких кривых обеспечивает близость точек фигуры, которые соответствуют точкам, близким на кривой. После получения списка элементов сети, упорядоченного в зависимости от расположения на кривой, достаточно разделить список на необходимое число частей в соответствии с установленным порядком. Получаемый в результате такого подхода метод носит в литературе наименование алгоритма деления сети с использованием кривых Пеано ( the space-filling curve technique ). Подробнее о методе можно прочитать в работах [, , ].
(рис 10.14) Пример разделения сети на 3 части с использованием кривых Пеано
В отличие от геометрических методов, комбинаторные алгоритмы
(см., например, [, ]) обычно оперируют не с сетью, а с
С самых общих позиций понятно, что при разделении
Общая схема алгоритма может быть описана при помощи следующего набора правил.
Алгоритм 10.2. Общая схема выполнения алгоритма деления
Iteration = 0.Iteration произвольной вершине Iteration номера Iteration + 1.Iteration = Iteration + 1.Для минимизации информационных зависимостей имеет смысл в
качестве начальной выбирать граничную вершину. Поиск такой
вершины можно осуществить методом, близким к рассмотренной схеме.
Так, перенумеровав вершины
Пример работы алгоритма приведен на рис. 10.15. Цифрами показаны номера, которые получили вершины в процессе разделения. Сплошной линией показана граница, разделяющая 2 подграфа. Также на рисунке показано лучшее решение (пунктирная линия). Очевидно, что полученное алгоритмом разбиение далеко от оптимального, так как в приведенном примере есть решение только с тремя пересеченными ребрами вместо пяти.
(рис 10.15) Пример работы алгоритма деления графов с учетом связности
В алгоритме Кернигана – Лина ( the Kernighan – Lin algorithm )
используется несколько иной подход для решения
Общая схема одной итерации алгоритма Кернигана – Лина может быть представлена следующим образом.
Алгоритм 10.3. Общая схема алгоритма Кернигана – Лина
Поясним дополнительно, что на шаге 2 итерации алгоритма
перестановка вершин каждой очередной пары осуществляется для
одного и того же разбиения
(рис 10.16) Пример перестановки двух вершин (выделены серым) в методе Кернигана – Лина
Рассмотренные алгоритмы разбиения
| Алгоритмы | Необходимость координатной информации | Точность | Время выполнения | Возможности для распараллеливания | |
|---|---|---|---|---|---|
| Покоординатное разбиение | Да | $$ullet$$ | $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ | |
| Рекурсивный инерционный метод деления пополам | Да | $$ullet$$ $$ullet$$ | $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ | |
| Деление с учетом связности | Нет | $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | |
| Алгоритм Кернигана - Лина | 1 итерация | Нет | $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | $$ullet$$ |
| 10 итераций | Нет | $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ | |
| 50 итераций | Нет | $$ullet$$ $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ $$ullet$$ | $$ullet$$ $$ullet$$ $$ullet$$ $$ullet$$ | |
Столбец "Необходимость координатной информации"
отмечает использование алгоритмом координатной информации об
элементах сети или вершинах
Столбец "Точность" дает качественную характеристику
величины приближения получаемых алгоритмом решений к оптимальным
вариантам разбиения
Столбец "Время выполнения" показывает относительное время, затрачиваемое различными алгоритмами разбиения. Каждый дополнительный закрашенный кружок соответствует увеличению времени разбиения примерно в 10 раз.
Столбец "Возможности для распараллеливания" характеризует свойства алгоритмов для параллельного выполнения. Алгоритм Кернигана – Лина при выполнении только одной итерации почти не поддается распараллеливанию. Этот же алгоритм при большем количестве итераций, а также метод деления с учетом связности могут быть распараллелены со средней эффективностью. Алгоритм покоординатного разбиения и рекурсивный инерционный метод деления пополам обладают высокими показателями для распараллеливания.
В лекции рассмотрен ряд алгоритмов для решения типовых задач
обработки
В подразделе 10.1 представлен
В подразделе 10.2 рассматривается
Рассматриваемая в подразделе 10.3 задача оптимального
разделения
Дополнительная информация по алгоритмам Флойда и Прима может быть получена, например, в [].
Подробное рассмотрение вопросов, связанных с проблемой
разделения
Параллельные алгоритмы разделения
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.