diff --git a/borschevskaya_anna_lab_5/README.md b/borschevskaya_anna_lab_5/README.md new file mode 100644 index 0000000..d0ae569 --- /dev/null +++ b/borschevskaya_anna_lab_5/README.md @@ -0,0 +1,30 @@ +# Отчет. Лабораторная работа 5 + +## Описание +В рамках лабораторной работы была реализована программа, которая производит умножение матриц с применением последовательного и паралелльного алгоритма. +При этом последовательный алгоритм достигается с помощью выделения одного потока на выполнение. + +При указании одного потока подзадачи по умножению матриц полностью выполняются одним потоком. В качестве подзадачи было +выбрано нахождение строки результирующей матрицы. + +По условию задания необходимо было замерить результаты выполнения алгоритмов на квадратных матрицах размерами 100x100, +300x300, 500x500. На всех прогонах можно увидеть, что последовательное выполнение умножения матриц происходит медленнее +в несколько раз медленее. При этом чем больше потоков выделяется для выполнения подзадач, тем быстрее выполняется +алгоритм параллельного умножения. + +Результаты представлены на следующих изображениях: +![100](images/100x100.PNG) +![300](images/300x300.PNG) +![500](images/500x500.PNG) + +## Как запустить +Необходимо иметь установленную JDK 21. Можно воспользоваться встроенным в нее компилятором (javac), а затем запустить исполняемый файл (java) +или запускать из среды разработки. +При запуске нужно указать аргументы командной строки: +1. размер матриц (integer) +2. режим отладки (boolean) - позволяет выводить в консоль исходные матрицы и промежуточные результаты работы + +## Видео-отчет +Работоспособность лабораторной работы можно оценить в следующем [видео](https://disk.yandex.ru/i/ZafQV9CGjBIKIw). +Запуск происходил через IDEA с различными конфигурациями запуска (отличался размер умножаемых матриц и параметр отладки), +чтобы увидеть результаты выполнения на матрицах всех размеров, необходимых по условию задачи. \ No newline at end of file diff --git a/borschevskaya_anna_lab_5/images/100x100.PNG b/borschevskaya_anna_lab_5/images/100x100.PNG new file mode 100644 index 0000000..d7c6850 Binary files /dev/null and b/borschevskaya_anna_lab_5/images/100x100.PNG differ diff --git a/borschevskaya_anna_lab_5/images/300x300.PNG b/borschevskaya_anna_lab_5/images/300x300.PNG new file mode 100644 index 0000000..d48518f Binary files /dev/null and b/borschevskaya_anna_lab_5/images/300x300.PNG differ diff --git a/borschevskaya_anna_lab_5/images/500x500.PNG b/borschevskaya_anna_lab_5/images/500x500.PNG new file mode 100644 index 0000000..1380f24 Binary files /dev/null and b/borschevskaya_anna_lab_5/images/500x500.PNG differ diff --git a/borschevskaya_anna_lab_5/matrix-mul/.gitignore b/borschevskaya_anna_lab_5/matrix-mul/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/borschevskaya_anna_lab_5/matrix-mul/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/borschevskaya_anna_lab_5/matrix-mul/pom.xml b/borschevskaya_anna_lab_5/matrix-mul/pom.xml new file mode 100644 index 0000000..f823988 --- /dev/null +++ b/borschevskaya_anna_lab_5/matrix-mul/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + ru.uni.rvip + matrix-mul + 1.0-SNAPSHOT + + + 21 + 21 + UTF-8 + + + \ No newline at end of file diff --git a/borschevskaya_anna_lab_5/matrix-mul/src/main/java/ru/uni/rvip/Main.java b/borschevskaya_anna_lab_5/matrix-mul/src/main/java/ru/uni/rvip/Main.java new file mode 100644 index 0000000..27af3b9 --- /dev/null +++ b/borschevskaya_anna_lab_5/matrix-mul/src/main/java/ru/uni/rvip/Main.java @@ -0,0 +1,98 @@ +package ru.uni.rvip; + +import java.util.ArrayList; +import java.util.Random; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +public class Main { + + public static void main(String[] args) { + var size = Integer.parseInt(args[0]); + var debugMode = Boolean.parseBoolean(args[1]); + System.out.printf("Размер матриц %dx%d\n", size, size); + + var matrix1 = createRandomMatrix(size); + if (debugMode) { + printMatrix(matrix1); + } + var matrix2 = createRandomMatrix(size); + if (debugMode) { + printMatrix(matrix2); + } + var startTime = System.currentTimeMillis(); + var result1 = mulMatrix(matrix1, matrix2, 1); // сначала передаем в метод 1 поток-исполнитель + var timeOfExecution = System.currentTimeMillis() - startTime; + if (debugMode) { + printMatrix(result1); + } + System.out.printf("Время умножения матриц с помощью последовательного алгоритма: %d ms\n", timeOfExecution); + + var threadCounts = new int[] {2, 4, 6, 8}; + for (var threadCount: threadCounts) { // тестирование на разном количестве потоков-исполнителей + startTime = System.currentTimeMillis(); + var result2 = mulMatrix(matrix1, matrix2, threadCount); + timeOfExecution = System.currentTimeMillis() - startTime; + if (debugMode) { + printMatrix(result2); + } + System.out.printf("Время умножения матриц с помощью параллельного алгоритма (%d threads): %d ms\n",threadCount, timeOfExecution); + } + + } + + private static int[][] createRandomMatrix(Integer size) { + var matrix = new int[size][size]; + var random = new Random(); + for (var i = 0; i < size; i++) { + for (var j = 0; j < size; j++) { + matrix[i][j] = random.nextInt(100); + } + } + return matrix; + } + + private static int[][] mulMatrix(int[][] matrix1, int[][] matrix2, Integer threadCount) { + if (matrix1[0].length != matrix2.length) { + throw new IllegalArgumentException("Количество столбцов первой матрицы должна соответствовать количеству строк второй матрицы"); + } + var rows = matrix2.length; + var columns = matrix1[0].length; + var result = new int[columns][rows]; + try (var executorService = Executors.newFixedThreadPool(threadCount)) { + var futures = new ArrayList>(); + for (int i = 0; i < rows; i++) { + final int rowI = i; + futures.add(executorService.submit(() -> calculate(rowI, matrix1, matrix2, result))); + } + + for (var future : futures) { + future.get(); + } + + executorService.shutdown(); + return result; + } catch (Exception ignored) { + throw new RuntimeException("Ошибка во время выполнения алгоритма"); + } + } + + private static int calculate(int i, int[][] matrix1, int[][] matrix2, int[][] result) { + for (int j = 0; j < matrix1[0].length; j++) { + result[i][j] = 0; + for (int k = 0; k < matrix2[0].length; k++) { + result[i][j] += matrix1[i][k] * matrix2[k][j]; + } + } + return i; + } + + private static void printMatrix(int[][] matrix) { + for (int[] ints : matrix) { + for (int elem : ints) { + System.out.printf("%5d\t", elem); + } + System.out.println(); + } + } +} \ No newline at end of file