belyaeva_ekaterina_lab_5 #115

Merged
Alexey merged 2 commits from belyaeva_ekaterina_lab_5 into main 2024-01-13 09:39:25 +04:00
12 changed files with 379 additions and 0 deletions

29
belyaeva_ekaterina_lab_5/.gitignore vendored Normal file
View File

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

View File

@ -0,0 +1,98 @@
# Лабораторная работа №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)

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

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

View File

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

View File

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