diff --git a/emelyanov_artem_lab_5/.idea/.gitignore b/emelyanov_artem_lab_5/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/emelyanov_artem_lab_5/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/emelyanov_artem_lab_5/.idea/emelyanov_artem_lab_5.iml b/emelyanov_artem_lab_5/.idea/emelyanov_artem_lab_5.iml new file mode 100644 index 0000000..b107a2d --- /dev/null +++ b/emelyanov_artem_lab_5/.idea/emelyanov_artem_lab_5.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/emelyanov_artem_lab_5/.idea/inspectionProfiles/Project_Default.xml b/emelyanov_artem_lab_5/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..db0f74e --- /dev/null +++ b/emelyanov_artem_lab_5/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/emelyanov_artem_lab_5/.idea/misc.xml b/emelyanov_artem_lab_5/.idea/misc.xml new file mode 100644 index 0000000..f03c948 --- /dev/null +++ b/emelyanov_artem_lab_5/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/emelyanov_artem_lab_5/.idea/modules.xml b/emelyanov_artem_lab_5/.idea/modules.xml new file mode 100644 index 0000000..4971c76 --- /dev/null +++ b/emelyanov_artem_lab_5/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/emelyanov_artem_lab_5/.idea/vcs.xml b/emelyanov_artem_lab_5/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/emelyanov_artem_lab_5/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/emelyanov_artem_lab_5/Benchmark.java b/emelyanov_artem_lab_5/Benchmark.java new file mode 100644 index 0000000..688334d --- /dev/null +++ b/emelyanov_artem_lab_5/Benchmark.java @@ -0,0 +1,22 @@ +public class Benchmark { + public static void main(String[] args) { + int[] sizes = {100, 300, 500}; + for (int size : sizes) { + int[][] matrixA = MatrixGenerator.generateMatrix(size); + int[][] matrixB = MatrixGenerator.generateMatrix(size); + + long startSequential = System.nanoTime(); + MatrixMultiplication.multiply(matrixA, matrixB, 1); + long endSequential = System.nanoTime(); + System.out.println("Последовательно (" + size + "x" + size + "): " + (endSequential - startSequential) / 1_000_000 + " ms"); + + for (int numThreads : new int[]{2, 4, 8}) { + long startParallel = System.nanoTime(); + MatrixMultiplication.multiply(matrixA, matrixB, numThreads); + long endParallel = System.nanoTime(); + System.out.println("Параллельно (" + size + "x" + size + ", " + numThreads + " потоков): " + + (endParallel - startParallel) / 1_000_000 + " ms"); + } + } + } +} diff --git a/emelyanov_artem_lab_5/Main.java b/emelyanov_artem_lab_5/Main.java new file mode 100644 index 0000000..ae1aef5 --- /dev/null +++ b/emelyanov_artem_lab_5/Main.java @@ -0,0 +1,33 @@ +public class Main{ + public static void main(String[] args){ + int[] sizes = {100, 300, 500}; + + for (int size : sizes) { + int[][] matrixA = MatrixGenerator.generateMatrix(size); + int[][] matrixB = MatrixGenerator.generateMatrix(size); + + System.out.println("Размер матрицы: " + size + "x" + size); + System.out.println("Матрица A:"); + MatrixPrinter.printMatrix(matrixA, 5); + System.out.println("Матрица B:"); + MatrixPrinter.printMatrix(matrixB, 5); + + long startSequential = System.nanoTime(); + int[][] resultSequential = MatrixMultiplication.multiply(matrixA, matrixB, 1); + long endSequential = System.nanoTime(); + System.out.println("Результат последовательного умножения:"); + MatrixPrinter.printMatrix(resultSequential, 5); + System.out.println("Время последовательного умножения: " + (endSequential - startSequential) / 1_000_000 + " ms"); + + for (int numThreads : new int[]{2, 4, 8}) { + long startParallel = System.nanoTime(); + int[][] resultParallel = MatrixMultiplication.multiply(matrixA, matrixB, numThreads); + long endParallel = System.nanoTime(); + System.out.println("Результат параллельного умножения (" + numThreads + " потоков):"); + MatrixPrinter.printMatrix(resultParallel, 5); + System.out.println("Время параллельного умножения: " + (endParallel - startParallel) / 1_000_000 + " ms"); + } + System.out.println("--------------------------------------------------"); + } + } +} diff --git a/emelyanov_artem_lab_5/MatrixGenerator.java b/emelyanov_artem_lab_5/MatrixGenerator.java new file mode 100644 index 0000000..3baecd7 --- /dev/null +++ b/emelyanov_artem_lab_5/MatrixGenerator.java @@ -0,0 +1,11 @@ +public class MatrixGenerator { + public static int[][] generateMatrix(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() * 100); + } + } + return matrix; + } +} diff --git a/emelyanov_artem_lab_5/MatrixMultiplication.java b/emelyanov_artem_lab_5/MatrixMultiplication.java new file mode 100644 index 0000000..3064fa6 --- /dev/null +++ b/emelyanov_artem_lab_5/MatrixMultiplication.java @@ -0,0 +1,44 @@ +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class MatrixMultiplication { + public static int[][] multiply(int[][] matrixA, int[][] matrixB, int numThreads) { + int n = matrixA.length; + int[][] result = new int[n][n]; + + if (numThreads == 1) { + // Последовательное умножение + for (int i = 0; i < n; i++) { + multiplyRow(matrixA, matrixB, result, i); + } + } else { + // Многопоточное умножение + ExecutorService executor = Executors.newFixedThreadPool(numThreads); + + for (int i = 0; i < n; i++) { + final int row = i; + executor.submit(() -> multiplyRow(matrixA, matrixB, result, row)); + } + + executor.shutdown(); + try { + // Ожидаем завершения всех задач + executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + return result; + } + + private static void multiplyRow(int[][] matrixA, int[][] matrixB, int[][] result, int row) { + int n = matrixA.length; + for (int j = 0; j < n; j++) { + for (int k = 0; k < n; k++) { + result[row][j] += matrixA[row][k] * matrixB[k][j]; + } + } + } +} diff --git a/emelyanov_artem_lab_5/MatrixPrinter.java b/emelyanov_artem_lab_5/MatrixPrinter.java new file mode 100644 index 0000000..488f4fb --- /dev/null +++ b/emelyanov_artem_lab_5/MatrixPrinter.java @@ -0,0 +1,24 @@ +public class MatrixPrinter { + public static void printMatrix(int[][] matrix) { + for (int[] row : matrix) { + for (int element : row) { + System.out.printf("%6d ", element); // Форматируем для лучшей читаемости + } + System.out.println(); + } + } + + public static void printMatrix(int[][] matrix, int maxSize) { + int n = Math.min(matrix.length, maxSize); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + System.out.printf("%6d ", matrix[i][j]); + } + System.out.println(); + } + + if (matrix.length > maxSize) { + System.out.println("..."); // Указываем, что матрица обрезана для отображения + } + } +} diff --git a/emelyanov_artem_lab_5/Readme.md b/emelyanov_artem_lab_5/Readme.md new file mode 100644 index 0000000..4d9707d --- /dev/null +++ b/emelyanov_artem_lab_5/Readme.md @@ -0,0 +1,17 @@ +# Перемножение матриц + +Данная работа посвящена реализации и сравнению последовательного и параллельного алгоритмов умножения квадратных матриц на языке Java. Целью является оценка производительности при использовании разного числа потоков. + +## Функциональность: +- Генерация матриц: Класс MatrixGenerator генерирует матрицы заданного размера с случайными значениями. +- Умножение матриц: Класс MatrixMultiplication реализует метод multiply, который в зависимости от числа потоков выполняет либо последовательное, либо параллельное умножение. +- Последовательное умножение выполняется с использованием одного потока. +- Параллельное умножение использует ExecutorService для распределения строк между потоками. +- Бенчмаркинг: Класс Benchmark измеряет время выполнения для матриц размером 100x100, 300x300, и 500x500 при использовании 1, 2, 4 и 8 потоков. +- Вывод результата: Класс MatrixPrinter позволяет выводить матрицы и результаты умножения в консоль, с возможностью ограничения отображаемых строк. +## Результаты: +В отчете отражены времена выполнения для каждого из подходов, что позволяет оценить, как число потоков влияет на скорость вычислений для матриц разного размера. + +![Снимок экрана от 2024-10-18 17-34-36.png](images/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA%20%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0%20%D0%BE%D1%82%202024-10-18%2017-34-36.png) + +Ссылка на видео: https://drive.google.com/file/d/1UD--N4oE9U9fQpLReXtB7G_-XGoD0iOX/view?usp=sharing \ No newline at end of file diff --git a/emelyanov_artem_lab_5/images/Снимок экрана от 2024-10-18 17-34-36.png b/emelyanov_artem_lab_5/images/Снимок экрана от 2024-10-18 17-34-36.png new file mode 100644 index 0000000..57d92f9 Binary files /dev/null and b/emelyanov_artem_lab_5/images/Снимок экрана от 2024-10-18 17-34-36.png differ