Merge pull request 'borschevskaya_anna_lab_5 is ready' (#63) from borschevskaya_anna_lab_5 into main

Reviewed-on: Alexey/DAS_2024_1#63
This commit is contained in:
Alexey 2024-10-16 16:50:14 +04:00
commit 430fad9ef4
7 changed files with 183 additions and 0 deletions

View File

@ -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 с различными конфигурациями запуска (отличался размер умножаемых матриц и параметр отладки),
чтобы увидеть результаты выполнения на матрицах всех размеров, необходимых по условию задачи.

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -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

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.uni.rvip</groupId>
<artifactId>matrix-mul</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -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<Future<Integer>>();
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();
}
}
}