diff --git a/belyaeva_ekaterina_lab_5/.gitignore b/belyaeva_ekaterina_lab_5/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/belyaeva_ekaterina_lab_5/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/belyaeva_ekaterina_lab_5/README.md b/belyaeva_ekaterina_lab_5/README.md new file mode 100644 index 0000000..7022e72 --- /dev/null +++ b/belyaeva_ekaterina_lab_5/README.md @@ -0,0 +1,87 @@ +# Лабораторная работа №5 + +## Задание + +Кратко: реализовать умножение двух больших квадратных матриц. + +Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности. + +## Ход работы + +### Последовательный алгоритм +``` +public static int[][] multiplyMatricesSequential(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + for (int i = 0; i < rows1; i++) { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[i][j] += matrix1[i][k] * matrix2[k][j]; + } + } + } + + return result; + } +``` +### Параллельный алгоритм +``` + public static int[][] multiplyMatricesParallel(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + int numberOfThreads = 5; // Количество потоков + ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); + + for (int i = 0; i < rows1; i++) { + final int row = i; + executor.execute(new Runnable() { + @Override + public void run() { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[row][j] += matrix1[row][k] * matrix2[k][j]; + } + } + } + }); + } + + executor.shutdown(); + while (!executor.isTerminated()) { + // Ожидаем завершения всех потоков + } + + return result; + } +``` + +## Результат + +Была проверка времени выполнения алгоритма для матриц размером 100х100, 300х300, 500х500 с разным количеством потоков. + +100х100, 1 поток +![100thr1.png](screenshots%2F100thr1.png) +100х100, 5 потоков +![100thr5.png](screenshots%2F100thr5.png) +300х300, 1 поток +![300thr1.png](screenshots%2F300thr1.png) +300х300, 5 потоков +![300thr5.png](screenshots%2F300thr5.png) +500х500, 1 поток +![500th1.png](screenshots%2F500th1.png) +500х500, 5 потоков +![500thr5.png](screenshots%2F500thr5.png) + +Из данных скриншотов видно, что в случае с матрицей 100х100 последовательный алгоритм работает лучше, чем параллельный. + +Для остальных матриц параллельный алгоритм работает лучше, а также увеличение кол-ва потоков уменьшает время выполнения алгоритма. (хотя в случае матрицы 100х100 - сильно увеличивает) + +Работоспособность показана в видео: [lab5.mp4](lab5.mp4) \ No newline at end of file diff --git a/belyaeva_ekaterina_lab_5/lab5.mp4 b/belyaeva_ekaterina_lab_5/lab5.mp4 new file mode 100644 index 0000000..138e9d1 Binary files /dev/null and b/belyaeva_ekaterina_lab_5/lab5.mp4 differ diff --git a/belyaeva_ekaterina_lab_5/screenshots/100thr1.png b/belyaeva_ekaterina_lab_5/screenshots/100thr1.png new file mode 100644 index 0000000..8bed8c3 Binary files /dev/null and b/belyaeva_ekaterina_lab_5/screenshots/100thr1.png differ diff --git a/belyaeva_ekaterina_lab_5/screenshots/100thr5.png b/belyaeva_ekaterina_lab_5/screenshots/100thr5.png new file mode 100644 index 0000000..1dbbb2c Binary files /dev/null and b/belyaeva_ekaterina_lab_5/screenshots/100thr5.png differ diff --git a/belyaeva_ekaterina_lab_5/screenshots/300thr1.png b/belyaeva_ekaterina_lab_5/screenshots/300thr1.png new file mode 100644 index 0000000..10dca83 Binary files /dev/null and b/belyaeva_ekaterina_lab_5/screenshots/300thr1.png differ diff --git a/belyaeva_ekaterina_lab_5/screenshots/300thr5.png b/belyaeva_ekaterina_lab_5/screenshots/300thr5.png new file mode 100644 index 0000000..e8a03e7 Binary files /dev/null and b/belyaeva_ekaterina_lab_5/screenshots/300thr5.png differ diff --git a/belyaeva_ekaterina_lab_5/screenshots/500th1.png b/belyaeva_ekaterina_lab_5/screenshots/500th1.png new file mode 100644 index 0000000..a934885 Binary files /dev/null and b/belyaeva_ekaterina_lab_5/screenshots/500th1.png differ diff --git a/belyaeva_ekaterina_lab_5/screenshots/500thr5.png b/belyaeva_ekaterina_lab_5/screenshots/500thr5.png new file mode 100644 index 0000000..165d0b8 Binary files /dev/null and b/belyaeva_ekaterina_lab_5/screenshots/500thr5.png differ diff --git a/belyaeva_ekaterina_lab_5/src/Matrix100x100.java b/belyaeva_ekaterina_lab_5/src/Matrix100x100.java new file mode 100644 index 0000000..ec62768 --- /dev/null +++ b/belyaeva_ekaterina_lab_5/src/Matrix100x100.java @@ -0,0 +1,84 @@ +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Matrix100x100 { + private static final int SIZE = 100; + + public static void main(String[] args) { + int[][] matrix1 = generateMatrix(SIZE, SIZE); + int[][] matrix2 = generateMatrix(SIZE, SIZE); + + long startTime = System.currentTimeMillis(); + int[][] resultSequential = multiplyMatricesSequential(matrix1, matrix2); + long endTime = System.currentTimeMillis(); + long sequentialTime = endTime - startTime; + + startTime = System.currentTimeMillis(); + int[][] resultParallel = multiplyMatricesParallel(matrix1, matrix2); + endTime = System.currentTimeMillis(); + long parallelTime = endTime - startTime; + + System.out.println("Sequential multiplication time: " + sequentialTime + " ms"); + System.out.println("Parallel multiplication time: " + parallelTime + " ms"); + } + + public static int[][] multiplyMatricesSequential(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + for (int i = 0; i < rows1; i++) { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[i][j] += matrix1[i][k] * matrix2[k][j]; + } + } + } + + return result; + } + + public static int[][] multiplyMatricesParallel(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + int numberOfThreads = 5; // Количество потоков + ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); + + for (int i = 0; i < rows1; i++) { + final int row = i; + executor.execute(new Runnable() { + @Override + public void run() { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[row][j] += matrix1[row][k] * matrix2[k][j]; + } + } + } + }); + } + + executor.shutdown(); + while (!executor.isTerminated()) { + // Ожидаем завершения всех потоков + } + + return result; + } + + public static int[][] generateMatrix(int rows, int columns) { + int[][] matrix = new int[rows][columns]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + matrix[i][j] = (int) (Math.random() * 10); + } + } + return matrix; + } +} \ No newline at end of file diff --git a/belyaeva_ekaterina_lab_5/src/Matrix300x300.java b/belyaeva_ekaterina_lab_5/src/Matrix300x300.java new file mode 100644 index 0000000..a5244c7 --- /dev/null +++ b/belyaeva_ekaterina_lab_5/src/Matrix300x300.java @@ -0,0 +1,84 @@ +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Matrix300x300 { + private static final int SIZE = 300; + + public static void main(String[] args) { + int[][] matrix1 = generateMatrix(SIZE, SIZE); + int[][] matrix2 = generateMatrix(SIZE, SIZE); + + long startTime = System.currentTimeMillis(); + int[][] resultSequential = multiplyMatricesSequential(matrix1, matrix2); + long endTime = System.currentTimeMillis(); + long sequentialTime = endTime - startTime; + + startTime = System.currentTimeMillis(); + int[][] resultParallel = multiplyMatricesParallel(matrix1, matrix2); + endTime = System.currentTimeMillis(); + long parallelTime = endTime - startTime; + + System.out.println("Sequential multiplication time: " + sequentialTime + " ms"); + System.out.println("Parallel multiplication time: " + parallelTime + " ms"); + } + + public static int[][] multiplyMatricesSequential(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + for (int i = 0; i < rows1; i++) { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[i][j] += matrix1[i][k] * matrix2[k][j]; + } + } + } + + return result; + } + + public static int[][] multiplyMatricesParallel(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + int numberOfThreads = 5; // Количество потоков + ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); + + for (int i = 0; i < rows1; i++) { + final int row = i; + executor.execute(new Runnable() { + @Override + public void run() { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[row][j] += matrix1[row][k] * matrix2[k][j]; + } + } + } + }); + } + + executor.shutdown(); + while (!executor.isTerminated()) { + // Ожидаем завершения всех потоков + } + + return result; + } + + public static int[][] generateMatrix(int rows, int columns) { + int[][] matrix = new int[rows][columns]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + matrix[i][j] = (int) (Math.random() * 10); + } + } + return matrix; + } +} \ No newline at end of file diff --git a/belyaeva_ekaterina_lab_5/src/Matrix500x500.java b/belyaeva_ekaterina_lab_5/src/Matrix500x500.java new file mode 100644 index 0000000..2ae656b --- /dev/null +++ b/belyaeva_ekaterina_lab_5/src/Matrix500x500.java @@ -0,0 +1,84 @@ +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Matrix500x500 { + private static final int SIZE = 500; + + public static void main(String[] args) { + int[][] matrix1 = generateMatrix(SIZE, SIZE); + int[][] matrix2 = generateMatrix(SIZE, SIZE); + + long startTime = System.currentTimeMillis(); + int[][] resultSequential = multiplyMatricesSequential(matrix1, matrix2); + long endTime = System.currentTimeMillis(); + long sequentialTime = endTime - startTime; + + startTime = System.currentTimeMillis(); + int[][] resultParallel = multiplyMatricesParallel(matrix1, matrix2); + endTime = System.currentTimeMillis(); + long parallelTime = endTime - startTime; + + System.out.println("Sequential multiplication time: " + sequentialTime + " ms"); + System.out.println("Parallel multiplication time: " + parallelTime + " ms"); + } + + public static int[][] multiplyMatricesSequential(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + for (int i = 0; i < rows1; i++) { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[i][j] += matrix1[i][k] * matrix2[k][j]; + } + } + } + + return result; + } + + public static int[][] multiplyMatricesParallel(int[][] matrix1, int[][] matrix2) { + int rows1 = matrix1.length; + int columns1 = matrix1[0].length; + int columns2 = matrix2[0].length; + + int[][] result = new int[rows1][columns2]; + + int numberOfThreads = 1; // Количество потоков + ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); + + for (int i = 0; i < rows1; i++) { + final int row = i; + executor.execute(new Runnable() { + @Override + public void run() { + for (int j = 0; j < columns2; j++) { + for (int k = 0; k < columns1; k++) { + result[row][j] += matrix1[row][k] * matrix2[k][j]; + } + } + } + }); + } + + executor.shutdown(); + while (!executor.isTerminated()) { + // Ожидаем завершения всех потоков + } + + return result; + } + + public static int[][] generateMatrix(int rows, int columns) { + int[][] matrix = new int[rows][columns]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + matrix[i][j] = (int) (Math.random() * 10); + } + } + return matrix; + } +} \ No newline at end of file