Merge pull request 'kutygin_andrey_lab_5_ready' (#124) from kutygin_andrey_lab_5 into main
Reviewed-on: #124
This commit is contained in:
commit
ac36e0ac8f
3
kutygin_andrey_lab_5/.idea/.gitignore
vendored
Normal file
3
kutygin_andrey_lab_5/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
6
kutygin_andrey_lab_5/.idea/jpa-buddy.xml
Normal file
6
kutygin_andrey_lab_5/.idea/jpa-buddy.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JpaBuddyIdeaProjectConfig">
|
||||||
|
<option name="renamerInitialized" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
9
kutygin_andrey_lab_5/.idea/misc.xml
Normal file
9
kutygin_andrey_lab_5/.idea/misc.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="18" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="jpab" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
kutygin_andrey_lab_5/.idea/modules.xml
Normal file
8
kutygin_andrey_lab_5/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/lab5.iml" filepath="$PROJECT_DIR$/lab5.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
62
kutygin_andrey_lab_5/README.md
Normal file
62
kutygin_andrey_lab_5/README.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
## Задание
|
||||||
|
Кратко: реализовать умножение двух больших квадратных матриц.
|
||||||
|
|
||||||
|
Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности.
|
||||||
|
|
||||||
|
### Ход работы
|
||||||
|
**Последовательный алгоритм**
|
||||||
|
|
||||||
|
public static int[][] multiplyMatricesSequential(int[][] matrix1, int[][] matrix2) {
|
||||||
|
|
||||||
|
int rows1 = matrix1.length;
|
||||||
|
|
||||||
|
int columns1 = matrix1[0].length;
|
||||||
|
|
||||||
|
int columns2 = matrix2[0].length;
|
||||||
|
|
||||||
|
var matrixResult = new int[size][size];
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
for (int m = 0; m < size; m++) {
|
||||||
|
matrixResult[i][j] += matrix1[i][m] * matrix2[m][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matrixResult;
|
||||||
|
Параллельный алгоритм
|
||||||
|
public static int[][] multiplyMatricesParallel(int[][] matrix1, int[][] matrix2) {
|
||||||
|
int rows1 = matrix1.length;
|
||||||
|
int columns1 = matrix1[0].length;
|
||||||
|
int columns2 = matrix2[0].length;
|
||||||
|
|
||||||
|
var matrixResult = new int[size][size];
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
|
||||||
|
int blockSize = size / nThreads;
|
||||||
|
|
||||||
|
for (int i = 0; i < nThreads; i++) {
|
||||||
|
int startRow = i * blockSize;
|
||||||
|
int endRow = (i + 1) * blockSize;
|
||||||
|
if (i == nThreads - 1) {
|
||||||
|
endRow = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int finalEndRow = endRow;
|
||||||
|
executorService.submit(() -> {
|
||||||
|
for (int row = startRow; row < finalEndRow; row++) {
|
||||||
|
for (int col = 0; col < size; col++) {
|
||||||
|
for (int m = 0; m < size; m++) {
|
||||||
|
matrixResult[row][col] += matrix1[row][m] * matrix2[m][col];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Результат
|
||||||
|
Была проверка времени выполнения алгоритма для матриц размером 100х100, 300х300, 500х500 с разным количеством потоков.
|
||||||
|
![sreenshot](screen.png)
|
||||||
|
|
||||||
|
Из данных скриншотов видно, что в случае с матрицей 100х100 последовательный алгоритм работает лучше, чем параллельный, в других случаях наоборот.
|
||||||
|
|
||||||
|
Для остальных матриц параллельный алгоритм работает лучше, а также увеличение кол-ва потоков уменьшает время выполнения алгоритма. (хотя в случае матрицы 100х100 - сильно увеличивает)
|
||||||
|
|
||||||
|
Видео: https://disk.yandex.ru/d/zeVdy1b0mC79cQ
|
11
kutygin_andrey_lab_5/lab5.iml
Normal file
11
kutygin_andrey_lab_5/lab5.iml
Normal 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$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
BIN
kutygin_andrey_lab_5/out/production/lab5/Main.class
Normal file
BIN
kutygin_andrey_lab_5/out/production/lab5/Main.class
Normal file
Binary file not shown.
BIN
kutygin_andrey_lab_5/screen.png
Normal file
BIN
kutygin_andrey_lab_5/screen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
103
kutygin_andrey_lab_5/src/Main.java
Normal file
103
kutygin_andrey_lab_5/src/Main.java
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
int nThreads = 8;
|
||||||
|
//100x100
|
||||||
|
var matrix1 = Matrix(100);
|
||||||
|
var matrix2 = Matrix(100);
|
||||||
|
//Последовательный алгоритм
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
int[][] matrixResult = SequentialMult(matrix1, matrix2, matrix1.length);
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("sequentially, 100x100, exec time: " + (endTime - startTime) + " ms");
|
||||||
|
//Параллельный алгоритм
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
matrixResult = ParallelMult(matrix1, matrix2, matrix1.length, nThreads);
|
||||||
|
endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("parallel, 100x100, (" + nThreads + " flows), exec time : " + (endTime - startTime) + " ms\n");
|
||||||
|
|
||||||
|
//300x300
|
||||||
|
matrix1 = Matrix(300);
|
||||||
|
matrix2 = Matrix(300);
|
||||||
|
//Последовательный алгоритм
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
matrixResult = SequentialMult(matrix1, matrix2, matrix1.length);
|
||||||
|
endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("sequentially, 300x300, exec time: " + (endTime - startTime) + " ms");
|
||||||
|
//Параллельный алгоритм
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
matrixResult = ParallelMult(matrix1, matrix2, matrix1.length, nThreads);
|
||||||
|
endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("parallel, 300x300, (" + nThreads + " flows), exec time : " + (endTime - startTime) + " ms\n");
|
||||||
|
|
||||||
|
//500x500
|
||||||
|
matrix1 = Matrix(500);
|
||||||
|
matrix2 = Matrix(500);
|
||||||
|
//Последовательный алгоритм
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
matrixResult = SequentialMult(matrix1, matrix2, matrix1.length);
|
||||||
|
endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("sequentially, 500x500, exec time: " + (endTime - startTime) + " ms");
|
||||||
|
//Параллельный алгоритм
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
matrixResult = ParallelMult(matrix1, matrix2, matrix1.length, nThreads);
|
||||||
|
endTime = System.currentTimeMillis();
|
||||||
|
System.out.println("parallel, 500x500, (" + nThreads + " flows), exec time : " + (endTime - startTime) + " ms\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[][] Matrix(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() * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[][] SequentialMult(int[][] matrix1, int[][] matrix2, int size) {
|
||||||
|
var matrixResult = new int[size][size];
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
for (int m = 0; m < size; m++) {
|
||||||
|
matrixResult[i][j] += matrix1[i][m] * matrix2[m][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matrixResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[][] ParallelMult(int[][] matrix1, int[][] matrix2, int size, int nThreads) throws InterruptedException {
|
||||||
|
var matrixResult = new int[size][size];
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
|
||||||
|
int blockSize = size / nThreads;
|
||||||
|
|
||||||
|
for (int i = 0; i < nThreads; i++) {
|
||||||
|
int startRow = i * blockSize;
|
||||||
|
int endRow = (i + 1) * blockSize;
|
||||||
|
if (i == nThreads - 1) {
|
||||||
|
endRow = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int finalEndRow = endRow;
|
||||||
|
executorService.submit(() -> {
|
||||||
|
for (int row = startRow; row < finalEndRow; row++) {
|
||||||
|
for (int col = 0; col < size; col++) {
|
||||||
|
for (int m = 0; m < size; m++) {
|
||||||
|
matrixResult[row][col] += matrix1[row][m] * matrix2[m][col];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
executorService.shutdown();
|
||||||
|
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||||||
|
|
||||||
|
return matrixResult;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user