diff --git a/mashkova_margarita_lab_5/README.md b/mashkova_margarita_lab_5/README.md new file mode 100644 index 0000000..15f9c0a --- /dev/null +++ b/mashkova_margarita_lab_5/README.md @@ -0,0 +1,27 @@ +# Лабораторная работа №3 +## ПИбд-42 Машкова Маргарита +## Задание +Требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). +В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание +со *), каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности. + +## Запуск программы +Запустить файл `Main` + +## Описание работы программы +В методе `main` вызывается метод `run`, для которого в качестве параметра передается размер квадратной матрицы `n`. +Создается пул потоков `executorService` с использованием `Executors.newFixedThreadPool`, где количество потоков равно +количеству доступных процессоров. +Генирируются две матрицы `a` и `b` заданного размера `n`. Вызываются соответсвующие методы вычисления произведения матриц +и измеряется время. Результаты выполнения выводятся в консоль. + +## Тесты +![Вывод в консоли](console.png) + +### Выводы +По оценки времени выполнения можно сделать вывод, что параллельный алгоритм позволяет ускорять процесс на больших размерах +матриц. Для маленьких матриц лучше использовать обычный алгоритм. Для размера матрицы 100*100 быстрее выполнился обычный +алгоритм. При последующем увеличении размера матрицы параллельный алгоритм позволяет ускорить вычислительный процесс. + +Ссылка на видео: +https://youtu.be/Vy6kO2mA8Fs \ No newline at end of file diff --git a/mashkova_margarita_lab_5/console.png b/mashkova_margarita_lab_5/console.png new file mode 100644 index 0000000..8263367 Binary files /dev/null and b/mashkova_margarita_lab_5/console.png differ diff --git a/mashkova_margarita_lab_5/src/Main.java b/mashkova_margarita_lab_5/src/Main.java new file mode 100644 index 0000000..0dc45fd --- /dev/null +++ b/mashkova_margarita_lab_5/src/Main.java @@ -0,0 +1,85 @@ +import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class Main { + + // Генерация квадратной матрицы размером n*n + public static int[][] generateMatrix(int n) { + int[][] matrix = new int[n][n]; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + matrix[i][j] = (int) (Math.random() * 100); + } + } + + return matrix; + } + + // Вычисление значения одного элемента результирующей матрицы + private static int calculateSingleValue(int i, int j, int[][] a, int[][] b) { + int result = 0; + for (int k = 0; k < a[0].length; ++k) { + result += a[i][k] * b[k][j]; + } + return result; + } + + // Обычное умножение матриц + public static int[][] multiplySync(int[][] a, int[][] b) { + final int[][] result = new int[a.length][b[0].length]; + for (int i = 0; i < a.length; ++i) { + for (int j = 0; j < b[0].length; ++j) { + result[i][j] = calculateSingleValue(i, j, a, b); + } + } + return result; + } + + // Параллельное умножение матриц + public static int[][] multiplyAsync(int[][] a, int[][] b, ExecutorService executor) throws InterruptedException { + final int[][] result = new int[a.length][b[0].length]; + for (int i = 0; i < a.length; ++i) { + final int fi = i; + executor.execute(() -> { + for (int j = 0; j < b[0].length; ++j) { + for (int k = 0; k < a[0].length; ++k) { + result[fi][j] += a[fi][k] * b[k][j]; + } + } + }); + } + executor.shutdown(); + executor.awaitTermination(1, TimeUnit.DAYS); + return result; + } + + public static void main(String[] args) throws InterruptedException { + System.out.println("Сравнение результатов\n"); + run(100); + run(300); + run(500); + } + + public static void run(int n) throws InterruptedException { + System.out.println(String.format("Размер матрицы = %d * %d", n, n)); + // Создание пула потоков (количество потоков = количеству доступных процессоров) + final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + final int[][] a = generateMatrix(n); + final int[][] b = generateMatrix(n); + + // Вычисление времени выполнения для обычного алгоритма + long time = System.currentTimeMillis(); + final int[][] productSync = multiplySync(a, b); + System.out.println("Время при обычном выполнении: " + (System.currentTimeMillis() - time)); + + // Вычисление времени выполнения для параллельного алгоритма + time = System.currentTimeMillis(); + final int[][] productAsync = multiplyAsync(a, b, executorService); + System.out.println("Время при параллельном выполнении: " + (System.currentTimeMillis() - time)); + System.out.println(); + } +} \ No newline at end of file