From 0e95d670efc13dca153bec556ded64eb0cded912 Mon Sep 17 00:00:00 2001 From: UrOldFriendSoul Date: Tue, 16 Jan 2024 12:23:28 +0400 Subject: [PATCH] kutygin_andrey_lab_5_ready --- kutygin_andrey_lab_5/.idea/.gitignore | 3 + kutygin_andrey_lab_5/.idea/jpa-buddy.xml | 6 + kutygin_andrey_lab_5/.idea/misc.xml | 9 ++ kutygin_andrey_lab_5/.idea/modules.xml | 8 ++ kutygin_andrey_lab_5/README.md | 62 +++++++++++ kutygin_andrey_lab_5/lab5.iml | 11 ++ .../out/production/lab5/Main.class | Bin 0 -> 4143 bytes kutygin_andrey_lab_5/screen.png | Bin 0 -> 29586 bytes kutygin_andrey_lab_5/src/Main.java | 103 ++++++++++++++++++ 9 files changed, 202 insertions(+) create mode 100644 kutygin_andrey_lab_5/.idea/.gitignore create mode 100644 kutygin_andrey_lab_5/.idea/jpa-buddy.xml create mode 100644 kutygin_andrey_lab_5/.idea/misc.xml create mode 100644 kutygin_andrey_lab_5/.idea/modules.xml create mode 100644 kutygin_andrey_lab_5/README.md create mode 100644 kutygin_andrey_lab_5/lab5.iml create mode 100644 kutygin_andrey_lab_5/out/production/lab5/Main.class create mode 100644 kutygin_andrey_lab_5/screen.png create mode 100644 kutygin_andrey_lab_5/src/Main.java diff --git a/kutygin_andrey_lab_5/.idea/.gitignore b/kutygin_andrey_lab_5/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/kutygin_andrey_lab_5/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/kutygin_andrey_lab_5/.idea/jpa-buddy.xml b/kutygin_andrey_lab_5/.idea/jpa-buddy.xml new file mode 100644 index 0000000..966d5f5 --- /dev/null +++ b/kutygin_andrey_lab_5/.idea/jpa-buddy.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_5/.idea/misc.xml b/kutygin_andrey_lab_5/.idea/misc.xml new file mode 100644 index 0000000..cac8158 --- /dev/null +++ b/kutygin_andrey_lab_5/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_5/.idea/modules.xml b/kutygin_andrey_lab_5/.idea/modules.xml new file mode 100644 index 0000000..03803f6 --- /dev/null +++ b/kutygin_andrey_lab_5/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_5/README.md b/kutygin_andrey_lab_5/README.md new file mode 100644 index 0000000..63781e7 --- /dev/null +++ b/kutygin_andrey_lab_5/README.md @@ -0,0 +1,62 @@ +## Задание +Кратко: реализовать умножение двух больших квадратных матриц. + +Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности. + +### Ход работы +**Последовательный алгоритм** + +public static int[][] multiplyMatricesSequential(int[][] matrix1, int[][] matrix2) { + +int rows1 = matrix1.length; + +int columns1 = matrix1[0].length; + +int columns2 = matrix2[0].length; + + var matrixResult = new int[size][size]; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + for (int m = 0; m < size; m++) { + matrixResult[i][j] += matrix1[i][m] * matrix2[m][j]; + } + } + } + return matrixResult; +Параллельный алгоритм +public static int[][] multiplyMatricesParallel(int[][] matrix1, int[][] matrix2) { +int rows1 = matrix1.length; +int columns1 = matrix1[0].length; +int columns2 = matrix2[0].length; + + var matrixResult = new int[size][size]; + + ExecutorService executorService = Executors.newFixedThreadPool(nThreads); + int blockSize = size / nThreads; + + for (int i = 0; i < nThreads; i++) { + int startRow = i * blockSize; + int endRow = (i + 1) * blockSize; + if (i == nThreads - 1) { + endRow = size; + } + + int finalEndRow = endRow; + executorService.submit(() -> { + for (int row = startRow; row < finalEndRow; row++) { + for (int col = 0; col < size; col++) { + for (int m = 0; m < size; m++) { + matrixResult[row][col] += matrix1[row][m] * matrix2[m][col]; + } + } + } + }); +Результат +Была проверка времени выполнения алгоритма для матриц размером 100х100, 300х300, 500х500 с разным количеством потоков. +![sreenshot](screen.png) + +Из данных скриншотов видно, что в случае с матрицей 100х100 последовательный алгоритм работает лучше, чем параллельный, в других случаях наоборот. + +Для остальных матриц параллельный алгоритм работает лучше, а также увеличение кол-ва потоков уменьшает время выполнения алгоритма. (хотя в случае матрицы 100х100 - сильно увеличивает) + +Видео: https://disk.yandex.ru/d/zeVdy1b0mC79cQ \ No newline at end of file diff --git a/kutygin_andrey_lab_5/lab5.iml b/kutygin_andrey_lab_5/lab5.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/kutygin_andrey_lab_5/lab5.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/kutygin_andrey_lab_5/out/production/lab5/Main.class b/kutygin_andrey_lab_5/out/production/lab5/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..79b7f9715ac191fda214bdc3d0c5ffa7eafb3077 GIT binary patch literal 4143 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�S?8ezM`N3i)&D^HkRv`WIgPe?(FL|MU&`YPiBY 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 J+FqF-5tE&p4=%W0tm3Yq$1ED&)`}` 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 literal 0 HcmV?d00001 diff --git a/kutygin_andrey_lab_5/src/Main.java b/kutygin_andrey_lab_5/src/Main.java new file mode 100644 index 0000000..7a12ad8 --- /dev/null +++ b/kutygin_andrey_lab_5/src/Main.java @@ -0,0 +1,103 @@ +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class Main { + public static void main(String[] args) throws InterruptedException { + int nThreads = 8; + //100x100 + var matrix1 = Matrix(100); + var matrix2 = Matrix(100); + //Последовательный алгоритм + long startTime = System.currentTimeMillis(); + int[][] matrixResult = SequentialMult(matrix1, matrix2, matrix1.length); + long endTime = System.currentTimeMillis(); + System.out.println("sequentially, 100x100, exec time: " + (endTime - startTime) + " ms"); + //Параллельный алгоритм + startTime = System.currentTimeMillis(); + matrixResult = ParallelMult(matrix1, matrix2, matrix1.length, nThreads); + endTime = System.currentTimeMillis(); + System.out.println("parallel, 100x100, (" + nThreads + " flows), exec time : " + (endTime - startTime) + " ms\n"); + + //300x300 + matrix1 = Matrix(300); + matrix2 = Matrix(300); + //Последовательный алгоритм + startTime = System.currentTimeMillis(); + matrixResult = SequentialMult(matrix1, matrix2, matrix1.length); + endTime = System.currentTimeMillis(); + System.out.println("sequentially, 300x300, exec time: " + (endTime - startTime) + " ms"); + //Параллельный алгоритм + startTime = System.currentTimeMillis(); + matrixResult = ParallelMult(matrix1, matrix2, matrix1.length, nThreads); + endTime = System.currentTimeMillis(); + System.out.println("parallel, 300x300, (" + nThreads + " flows), exec time : " + (endTime - startTime) + " ms\n"); + + //500x500 + matrix1 = Matrix(500); + matrix2 = Matrix(500); + //Последовательный алгоритм + startTime = System.currentTimeMillis(); + matrixResult = SequentialMult(matrix1, matrix2, matrix1.length); + endTime = System.currentTimeMillis(); + System.out.println("sequentially, 500x500, exec time: " + (endTime - startTime) + " ms"); + //Параллельный алгоритм + startTime = System.currentTimeMillis(); + matrixResult = ParallelMult(matrix1, matrix2, matrix1.length, nThreads); + endTime = System.currentTimeMillis(); + System.out.println("parallel, 500x500, (" + nThreads + " flows), exec time : " + (endTime - startTime) + " ms\n"); + } + + public static int[][] Matrix(int size) { + int[][] matrix = new int[size][size]; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + matrix[i][j] = (int) (Math.random() * 1000); + } + } + return matrix; + } + + public static int[][] SequentialMult(int[][] matrix1, int[][] matrix2, int size) { + var matrixResult = new int[size][size]; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + for (int m = 0; m < size; m++) { + matrixResult[i][j] += matrix1[i][m] * matrix2[m][j]; + } + } + } + return matrixResult; + } + + public static int[][] ParallelMult(int[][] matrix1, int[][] matrix2, int size, int nThreads) throws InterruptedException { + var matrixResult = new int[size][size]; + + ExecutorService executorService = Executors.newFixedThreadPool(nThreads); + int blockSize = size / nThreads; + + for (int i = 0; i < nThreads; i++) { + int startRow = i * blockSize; + int endRow = (i + 1) * blockSize; + if (i == nThreads - 1) { + endRow = size; + } + + int finalEndRow = endRow; + executorService.submit(() -> { + for (int row = startRow; row < finalEndRow; row++) { + for (int col = 0; col < size; col++) { + for (int m = 0; m < size; m++) { + matrixResult[row][col] += matrix1[row][m] * matrix2[m][col]; + } + } + } + }); + } + + executorService.shutdown(); + executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + + return matrixResult; + } +} \ No newline at end of file