Merge pull request 'emelyanov_artem_lab_5' (#74) from emelyanov_artem_lab_5 into main

Reviewed-on: #74
This commit is contained in:
Alexey 2024-10-19 12:56:19 +04:00
commit d82f47e04c
13 changed files with 198 additions and 0 deletions

View File

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

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,8 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,java.lang.foreign.Arena,ofAuto,java.lang.foreign.Arena,global,java.util.concurrent.Executors,newFixedThreadPool" />
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="23" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/emelyanov_artem_lab_5.iml" filepath="$PROJECT_DIR$/.idea/emelyanov_artem_lab_5.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@ -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");
}
}
}
}

View File

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

View File

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

View File

@ -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];
}
}
}
}

View File

@ -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("..."); // Указываем, что матрица обрезана для отображения
}
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB