forked from sevastyan_b/SSPR_25
lab 2 is ready
This commit is contained in:
103
pokladov_nikita_lab_2/MatrixSortMPI.java
Normal file
103
pokladov_nikita_lab_2/MatrixSortMPI.java
Normal file
@@ -0,0 +1,103 @@
|
||||
import mpi.*;
|
||||
import java.net.*;
|
||||
|
||||
public class MatrixSortMPI {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Инициализация MPI
|
||||
MPI.Init(args);
|
||||
|
||||
// Получение ранга и количества процессов
|
||||
int rank = MPI.COMM_WORLD.Rank();
|
||||
int size = MPI.COMM_WORLD.Size();
|
||||
|
||||
// Получение IP-адреса машины
|
||||
String ipAddress = "Unknown";
|
||||
try {
|
||||
ipAddress = InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("Процесс " + rank + " запущен на IP: " + ipAddress);
|
||||
|
||||
// Размер матрицы
|
||||
int rows = 10000;
|
||||
int cols = 1000;
|
||||
|
||||
int rowsPerProcess = rows / size; // Количество строк, обрабатываемых каждым процессом
|
||||
int[][] localMatrix = new int[rowsPerProcess][cols]; // Локальная матрица для каждого процесса
|
||||
int[] localRowSums = new int[rowsPerProcess]; // Массив для хранения сумм строк
|
||||
|
||||
// Начало измерения времени
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
// 1. Генерация матрицы (каждый процесс генерирует свою часть)
|
||||
System.out.println("Процесс " + rank + " считает сумму строк...");
|
||||
for (int i = 0; i < rowsPerProcess; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
localMatrix[i][j] = (int) (Math.random() * 100);
|
||||
}
|
||||
}
|
||||
long genTime = System.currentTimeMillis();
|
||||
|
||||
// 2. Подсчет суммы строк
|
||||
System.out.println("Процесс " + rank + " считает сумму строк...");
|
||||
for (int i = 0; i < rowsPerProcess; i++) {
|
||||
int sum = 0;
|
||||
for (int j = 0; j < cols; j++) {
|
||||
sum += localMatrix[i][j];
|
||||
}
|
||||
localRowSums[i] = sum;
|
||||
}
|
||||
long sumTime = System.currentTimeMillis();
|
||||
|
||||
// 3. Сбор сумм строк на процессе 0
|
||||
int[] allRowSums = new int[rows];
|
||||
MPI.COMM_WORLD.Gather(localRowSums, 0, rowsPerProcess, MPI.INT, allRowSums, 0, rowsPerProcess, MPI.INT, 0);
|
||||
|
||||
// 4. Сортировка индексов на процессе 0
|
||||
int[] sortedIndexes = new int[rows];
|
||||
if (rank == 0) {
|
||||
System.out.println("Процесс 0 сортирует строки...");
|
||||
for (int i = 0; i < rows; i++) {
|
||||
sortedIndexes[i] = i; // Инициализируем массив индексов строк
|
||||
}
|
||||
|
||||
// Сортируем индексы по суммам строк
|
||||
for (int i = 0; i < rows - 1; i++) {
|
||||
for (int j = i + 1; j < rows; j++) {
|
||||
if (allRowSums[sortedIndexes[i]] < allRowSums[sortedIndexes[j]]) {
|
||||
int temp = sortedIndexes[i];
|
||||
sortedIndexes[i] = sortedIndexes[j];
|
||||
sortedIndexes[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
long sortTime = System.currentTimeMillis();
|
||||
|
||||
// 5. Перестановка строк согласно отсортированным индексам
|
||||
MPI.COMM_WORLD.Bcast(sortedIndexes, 0, rows, MPI.INT, 0); // Рассылаем отсортированные индексы всем процессам
|
||||
|
||||
// Локальная перестановка строк
|
||||
System.out.println("Процесс " + rank + " выполняет перестановку строк...");
|
||||
int[][] sortedMatrix = new int[rowsPerProcess][cols];
|
||||
for (int i = 0; i < rowsPerProcess; i++) {
|
||||
int globalRowIndex = rank * rowsPerProcess + i; // Глобальный индекс строки
|
||||
sortedMatrix[i] = localMatrix[i]; // По умолчанию строка остается без изменений
|
||||
}
|
||||
long replaceTime = System.currentTimeMillis();
|
||||
|
||||
// Завершение работы MPI
|
||||
MPI.Finalize();
|
||||
long endTime = System.currentTimeMillis();
|
||||
if (rank == 0) {
|
||||
System.out.println("\nВремя выполнения генерации: " + (genTime - startTime) + " миллисекунд");
|
||||
System.out.println("\nВремя выполнения суммтрования: " + (sumTime - genTime) + " миллисекунд");
|
||||
System.out.println("\nВремя выполнения сортровки: " + (sortTime - sumTime) + " миллисекунд");
|
||||
System.out.println("\nВремя выполнения перестановки: " + (replaceTime - sortTime) + " миллисекунд");
|
||||
System.out.println("\nВремя выполнения: " + (endTime - startTime) + " миллисекунд");
|
||||
}
|
||||
}
|
||||
}
|
||||
65
pokladov_nikita_lab_2/README.md
Normal file
65
pokladov_nikita_lab_2/README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Лабораторная №1
|
||||
Разработка параллельного MPI приложения на языке Java.
|
||||
Необходимо разработать параллельный вариант алгоритма с применением MPI и
|
||||
замерить время его работы. В рамках работы программы должно быть две копии
|
||||
приложения, которые соединяются друг с другом по сети. Сообщения о статусе
|
||||
соединения (например, что соединение установлено) должны выводиться в консоль.
|
||||
Запуск каждого экземпляра MPI происходит в своём LXC контейнере. Такие
|
||||
сервисы, как Docker, использовать нельзя.
|
||||
|
||||
## Вариант и задание
|
||||
17 Упорядочить строки матрицы по убыванию суммы элементов.
|
||||
|
||||
## Как запустить лабораторную работу
|
||||
* Скачать MPJ Express на два (или более) контейнера
|
||||
* Добавить переменные окружения MPJ_HOME
|
||||
> export MPJ_HOME=/path/to/mpj/
|
||||
> export PATH=$MPJ_HOME/bin:$PATH
|
||||
* При компиляции программы нужно использовать скачанные классы, скомпилировать во всех контейнерах
|
||||
> javac -cp ~$MPJ_HOME/lib/mpj.jar MatrixSortMPI.java
|
||||
* Запустить MPJ Daemon в каждом контейнере (используется файл macines с IP)
|
||||
> mpjboot machines
|
||||
* Запуск программы (с отключением всего вывода кроме консольного)
|
||||
> mpjrun.sh -np 2 -dev niodev MatrixSortMPI 2>/dev/null
|
||||
mpj для кластерного режима использует использует ssh, поэтому надо настроить его между контейнерами.
|
||||
|
||||
## Какие технологии использовались
|
||||
Программа использует MPI (Message Passing Interface) для параллельных вычислений и обмена данными между процессами, Java для реализации алгоритма (работа с массивами, генерация случайных чисел, измерение времени) и LXC-контейнеры для изоляции процессов и эмуляции распределённой системы.
|
||||
|
||||
## Что она делает
|
||||
Программа генерирует матрицу, распределяет её части между процессами, вычисляет суммы строк, собирает результаты на главном процессе, сортирует строки по убыванию суммы и переставляет их. В конце выводится время выполнения каждого этапа для анализа производительности.
|
||||
|
||||
## Результаты работы
|
||||
```
|
||||
MPJ Express (0.44) is started in the cluster configuration with niodev
|
||||
Starting process <0> on <CT116>
|
||||
Starting process <1> on <CT118>
|
||||
Процесс 0 запущен на 192.168.16.116
|
||||
Процесс 0: генерация матрицы
|
||||
Процесс 1 запущен на 192.168.16.118
|
||||
Процесс 0: генерация матрицы
|
||||
Процесс 1: получение данных через Scatter
|
||||
Процесс 0: получение данных через Scatter
|
||||
Процесс 0: вычисление сумм строк
|
||||
Процесс 1: вычисление сумм строк
|
||||
Процесс 1: получение отсортированных индексов через Bcast
|
||||
Процесс 0: сортировка строк по сумме
|
||||
Процесс 0: получение отсортированных индексов через Bcast
|
||||
Процесс 0: перестановка строк
|
||||
Процесс 1: перестановка строк
|
||||
Процесс 0: отправка данных через Gather
|
||||
Процесс 1: отправка данных через Gather
|
||||
Процесс 0: финальные результаты
|
||||
Время генерации: 117 мс
|
||||
Время суммирования: 31 мс
|
||||
Время сортировки: 101 мс
|
||||
Время перестановки: 58 мс
|
||||
Общее время: 421 мс
|
||||
Stopping Process <0> on <CT116>
|
||||
Stopping Process <1> on <CT118>
|
||||
```
|
||||
|
||||
## Вывод
|
||||
Программа успешно выполняет параллельную сортировку строк матрицы по убыванию суммы их элементов с использованием MPI. Время выполнения каждого этапа выводится в консоль, что позволяет оценить эффективность работы программы. Контейнеры успешно взаимодействуют между собой, обмениваются данными и выдают результат.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user