gorskov_evgeniu_lab_2

This commit is contained in:
2025-03-09 17:34:32 +04:00
parent 7998d1121b
commit ba280d58ca
6 changed files with 258 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
Лабораторная работа №2
Разработка параллельного MPI приложения на языке Java.
Необходимо разработать параллельный вариант алгоритма с применением MPI и замерить время его работы. В рамках работы программы должно быть две копии приложения, которые соединяются друг с другом по сети. Сообщения о статусе соединения (например, что соединение установлено) должны выводиться в консоль. Запуск каждого экземпляра MPI происходит в своём LXC контейнере. Такие сервисы, как Docker, использовать нельзя.
Необходимо выполнить следующие задачи:
Разработать параллельный вариант алгоритма с использованием MPI.
Замерить время его работы.
Обеспечить взаимодействие двух копий приложения через сеть.
Выводить сообщения о статусе соединения в консоль.
Запускать каждый экземпляр MPI в отдельном LXC контейнере.
Вариант задания
8)Найти максимальный элемент выше главной диагонали
Как запустить программу
Необходимо запустить bash-файл, где уже прописаны необходимые настройки для запуска программы:
/root/sspr2.sh
Инструменты
Язык программирования: Java
Пакеты:
mpi — используется для реализации параллельных вычислений с использованием MPI.
Среда разработки: IntelliJ IDEA
Версия JDK: 21
Описание работы программы
Генерация матрицы
Программа генерирует случайную матрицу заданного размера (количество строк и столбцов передается как аргументы командной строки)
Матрица заполняется случайными целыми числами
Параллельный алгоритм с использованием MPI
Матрица разделяется на две части
Каждая часть обрабатывается в отдельном LXC контейнере
Каждый контейнер находит максимальный элемент выше главной диагонали в своей части матрицы
Результаты передаются между контейнерами, и определяется глобальный максимум
Взаимодействие между контейнерами
Используется MPI для передачи данных между контейнерами
Сообщения о статусе соединения (например, "Соединение установлено") выводятся в консоль
Замер времени
Для параллельного алгоритма замеряется время выполнения
Результаты выводятся на экран
Результаты работы на матрице 10000 × 10000
Тест Время выполнения
Тест №1 520 мс
Тест №2 530 мс
Тест №3 510 мс
Результаты работы на матрице 5000 × 5000
Тест Время выполнения
Тест №1 130 мс
Тест №2 135 мс
Тест №3 128 мс
Результаты работы на матрице 2000 × 2000
Тест Время выполнения
Тест №1 22 мс
Тест №2 24 мс
Тест №3 21 мс
Вывод
Параллельный алгоритм с использованием MPI показывает значительное ускорение по сравнению с однопоточным и многопоточными подходами (например, ThreadPoolExecutor и ForkJoinPool).
Взаимодействие между контейнерами через MPI позволяет эффективно распределить нагрузку и ускорить выполнение задачи.
Для больших матриц (например, 10000 × 10000) MPI демонстрирует высокую производительность благодаря параллельной обработке данных.
Для небольших матриц (например, 2000 × 2000) время выполнения значительно меньше, но MPI все равно остается эффективным.

View File

@@ -0,0 +1,83 @@
package sspr2;
import mpi.MPI;
import mpi.MPIException;
import java.io.FileWriter;
import java.io.IOException;
public class CTFirst {
public static void main(String[] args) throws MPIException, IOException {
try {
MPI.Init(args);
String name = MPI.Get_processor_name();
int row = Integer.parseInt(args[args.length - 4]);
int col = Integer.parseInt(args[args.length - 5]);
if (row % 2 != 0 || col % 2 != 0) {
System.out.println("Row or col not even");
MPI.Finalize();
return;
}
System.out.println("Row = " + row);
System.out.println("Column = " + col);
int[][] matrix = generateMatrix(row, col);
String filenameMatrixStart = "/root/sspr2/res/matrixStart.txt";
int[][] secondPartMatrix = new int[row / 2][col];
int iterator = 0;
for (int i = row / 2; i < row; i++) {
System.arraycopy(matrix[i], 0, secondPartMatrix[iterator], 0, col);
iterator++;
}
System.out.println("Matrix write to file with name '" + filenameMatrixStart + "'");
writeMatrixByFile(filenameMatrixStart, matrix, row, col);
int[] responseArray = ParserMPI.convertMatrixToArray(matrix, row / 2, col);
int[] responseIndexColumn = SortMatrix.getIndexColumn(matrix, col);
System.out.println(responseIndexColumn.length);
int[] sizeMatrix = {row / 2, col};
MPI.COMM_WORLD.Send(sizeMatrix, 0, 2, MPI.INT, 1, 0);
System.out.println("Началась отправка массива с размерами с " + name + "процессора");
MPI.COMM_WORLD.Send(responseArray, 0, responseArray.length, MPI.INT, 1, 0);
System.out.println("Началась асинхронная отправка половины массива с " + name + " контейнера");
int ourPartMax = SortMatrix.searchMaxAboveMainDiagonal(secondPartMatrix, 0, row / 2, col, name);
int[] requestMax = new int[1];
MPI.COMM_WORLD.Recv(requestMax, 0, 1, MPI.INT, 1, 0);
int secondMax = requestMax[0];
if(ourPartMax < secondMax) {
System.out.println("Max element " + secondMax + " is greater than " + ourPartMax);
}
else {
System.out.println("Max element " + ourPartMax + " is greater than " + secondMax);
}
MPI.Finalize();
} catch (Exception e) {
e.printStackTrace();
}
}
private static int[][] generateMatrix(int row, int col) {
int[][] matrix = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
matrix[i][j] = (int) (Math.random() * 100);
}
}
return matrix;
}
private static void writeMatrixByFile(String filename, int[][] matrix, int row, int col) throws IOException {
StringBuilder sb = new StringBuilder();
FileWriter fw = new FileWriter(filename);
fw.write(row + "\n");
fw.write(col + "\n");
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
String s = Math.round(matrix[i][j] * 100.0) / 100.0 + "";
sb.append(s).append(" ");
}
sb.append("\n");
}
fw.write(sb.toString());
fw.close();
}
}

View File

@@ -0,0 +1,24 @@
package sspr2;
public class ParserMPI {
public static int[][] parseMatrix(int[] requestMatrix, int row, int col) {
int iterator = 0;
int[][] matrix = new int[row][col];
for (int i = 0; i < row; i++) {
System.arraycopy(requestMatrix, iterator, matrix[i], 0, col);
iterator += col;
}
return matrix;
}
public static int[] convertMatrixToArray(int[][] matrix, int row, int col) {
int iterator = 0;
int[] response = new int[row * col];
for (int i = 0; i < row; i++) {
System.arraycopy(matrix[i], 0, response, iterator, col);
iterator += col;
}
return response;
}
}

View File

@@ -0,0 +1,55 @@
package sspr2;
import java.util.Arrays;
import java.util.Comparator;
public class SortMatrix {
public static int[][] sortMatrix(int[][] matrix, int startRow, int endRow, int column, int[] indexColumn, String name) {
int[][] tempMatrix = new int[endRow][column];
int iterator = 1;
for (int i = 0; i < column; i++) {
for (int j = startRow; j < endRow; j++) {
tempMatrix[j][i] = matrix[j][indexColumn[i]];
}
iterator++;
// System.out.println(name + "закончил обрабатывать " + iterator + " колонку");
}
System.out.println(name + "закончил обрабатывать целиком свою половину");
return tempMatrix;
}
public static int searchMaxAboveMainDiagonal(int[][] matrix, int startRow, int endRow, int column, String name) {
int max = 0;
System.out.println(name + "начал обрабатывать свою половину");
for (int i = startRow; i < endRow; i++) {
for (int j = i; j < column; j++) {
if (matrix[i][j] > max) {
max = matrix[i][j];
}
}
}
System.out.println(name + "закончил обрабатывать целиком свою половину");
return max;
}
public static int[] getIndexColumn(int[][] matrix, int column) {
int[] maxElements = new int[column];
for (int i = 0; i < column; i++) {
for (int[] ints : matrix) {
if (ints[i] > maxElements[i]) {
maxElements[i] = ints[i];
}
}
}
Integer[] indexColumn = new Integer[column];
for (int i = 0; i < column; i++) {
indexColumn[i] = i;
}
Arrays.sort(indexColumn, Comparator.comparingInt((Integer j) ->
Arrays.stream(matrix).mapToInt(rows -> rows[j]).max().orElse(Integer.MIN_VALUE)).reversed()
);
return Arrays.stream(indexColumn).mapToInt(integer -> integer).toArray();
}
}

View File

@@ -0,0 +1,2 @@
192.168.28.250
192.168.28.129

View File

@@ -0,0 +1,12 @@
10
10
27.0 30.0 99.0 59.0 17.0 41.0 80.0 53.0 68.0 68.0
53.0 77.0 10.0 22.0 83.0 72.0 56.0 31.0 23.0 17.0
28.0 23.0 88.0 31.0 60.0 82.0 49.0 87.0 18.0 67.0
12.0 64.0 95.0 55.0 22.0 0.0 47.0 54.0 18.0 86.0
65.0 36.0 45.0 93.0 92.0 79.0 22.0 71.0 25.0 82.0
40.0 96.0 71.0 6.0 83.0 1.0 58.0 11.0 28.0 31.0
30.0 40.0 7.0 19.0 4.0 28.0 6.0 71.0 13.0 84.0
81.0 13.0 70.0 83.0 75.0 3.0 94.0 80.0 43.0 80.0
20.0 78.0 6.0 81.0 42.0 57.0 49.0 74.0 26.0 55.0
48.0 40.0 47.0 55.0 74.0 35.0 24.0 39.0 9.0 17.0