Merge pull request 'lobashov_ivan_lab_5 is ready' (#440) from lobashov_ivan_lab_5 into main

Reviewed-on: #440
This commit was merged in pull request #440.
This commit is contained in:
2025-12-08 23:07:28 +04:00
3 changed files with 208 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Matrix {
public static double[][] generateMatrix(int n) {
Random rand = new Random();
double[][] matrix = new double[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = rand.nextDouble() * 10;
}
}
return matrix;
}
public static double[][] multiplySequential(double[][] A, double[][] B) {
int n = A.length;
double[][] C = new double[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
double sum = 0;
for (int k = 0; k < n; k++) {
sum += A[i][k] * B[k][j];
}
C[i][j] = sum;
}
}
return C;
}
public static double[][] multiplyParallel(double[][] A, double[][] B, int numThreads) throws InterruptedException {
int n = A.length;
double[][] C = new double[n][n];
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
int rowsPerThread = (n + numThreads - 1) / numThreads;
for (int t = 0; t < numThreads; t++) {
final int startRow = t * rowsPerThread;
final int endRow = Math.min(startRow + rowsPerThread, n);
executor.submit(() -> {
for (int i = startRow; i < endRow; i++) {
for (int j = 0; j < n; j++) {
double sum = 0;
for (int k = 0; k < n; k++) {
sum += A[i][k] * B[k][j];
}
C[i][j] = sum;
}
}
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);
return C;
}
public static void runBenchmark(int size, int numThreads) throws InterruptedException {
System.out.println("\n=== Размер матрицы: " + size + "x" + size + " ===");
System.out.println("Генерация матриц...");
double[][] A = generateMatrix(size);
double[][] B = generateMatrix(size);
System.out.println("Запуск последовательного алгоритма...");
long startSeq = System.currentTimeMillis();
double[][] C_seq = multiplySequential(A, B);
long endSeq = System.currentTimeMillis();
long seqTime = endSeq - startSeq;
System.out.println("Запуск параллельного алгоритма (" + numThreads + " потоков)...");
long startPar = System.currentTimeMillis();
double[][] C_par = multiplyParallel(A, B, numThreads);
long endPar = System.currentTimeMillis();
long parTime = endPar - startPar;
double speedup = (double) seqTime / parTime;
double efficiency = (speedup / numThreads) * 100;
System.out.println("Результаты:");
System.out.println(" Последовательное умножение: " + seqTime + " мс");
System.out.println(" Параллельное умножение: " + parTime + " мс");
System.out.printf(" Ускорение: %.2fx%n", speedup);
System.out.printf(" Эффективность: %.1f%%%n", efficiency);
}
public static void runThreadScalingBenchmark(int size) throws InterruptedException {
double[][] A = generateMatrix(size);
double[][] B = generateMatrix(size);
long startSeq = System.currentTimeMillis();
multiplySequential(A, B);
long endSeq = System.currentTimeMillis();
long seqTime = endSeq - startSeq;
System.out.println("Последовательное время: " + seqTime + " мс");
int[] threadCounts = {1, 2, 4, 8, 16};
for (int threads : threadCounts) {
long startPar = System.currentTimeMillis();
multiplyParallel(A, B, threads);
long endPar = System.currentTimeMillis();
long parTime = endPar - startPar;
double speedup = (double) seqTime / parTime;
double efficiency = (speedup / threads) * 100;
System.out.printf(" %2d потоков: %5d мс, ускорение: %5.2fx, эффективность: %5.1f%%%n",
threads, parTime, speedup, efficiency);
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("Бенчмарк умножения матриц");
System.out.println("==========================");
int[] sizes = {100, 300, 500};
int defaultThreads = 4;
System.out.println("\nОсновные бенчмарки:");
for (int size : sizes) {
runBenchmark(size, defaultThreads);
}
runThreadScalingBenchmark(500);
System.out.println("\nВсе бенчмарки выполнены.");
}
}

View File

@@ -0,0 +1,68 @@
# Лабораторная работа 5
**Тема**: Параллельное и последовательное умножение матриц на Java
# Технологии
Для лабораторной работы использовались следующие технологии:
1. Java 17 (Язык программированя)
2. java.util.concurrent (для многопоточности)
# Что делает программа
Программа реализует два алгоритма умножения квадратных матриц:
* Последовательный алгоритм - классическое тройное вложенное циклы
* Параллельный алгоритм - распределение строк матрицы между потоками
Ключевые особенности реализации:
* Распределение строк матрицы между потоками равномерно
* Использование ExecutorService для управления потоками
* Автоматическая генерация тестовых матриц
* Измерение времени выполнения и расчет эффективности
# Тесты
В программе используются бенчмарки и 4 потока в параллельном алгоритме
```
int[] sizes = {100, 300, 500};
int numThreads = 4
```
можно изменять размеры матриц и количество потоков
```
int[] sizes = {200, 400, 600};
int numThreads = 2
```
# Сравнение результатов
1. Матрица 100x100 :
Последовательное умножение: 3 мс
Параллельное умножение: 20 мс
Ускорение: 0,15x
Эффективность: 3,8%
* Вывод: Для небольших матриц накладные расходы на создание и синхронизацию потоков превышают выгоду от параллелизации. Время запуска потоков и управления ими становится доминирующим фактором.
2. Матрица 300х300:
Последовательное умножение: 28 мс
Параллельное умножение: 9 мс
Ускорение: 3,11x
Эффективность: 77,8%
* Вывод: При размере 300×300 параллельный алгоритм показывает хорошее ускорение с высокой эффективностью использования потоков.
3. Матрица 500х500:
Последовательное умножение: 138 мс
Параллельное умножение: 48 мс
Ускорение: 2,88x
Эффективность: 71,9%
* Вывод: Для больших матриц сохраняется значительное ускорение, хотя эффективность немного снижается из-за возрастающих затрат на синхронизацию.
**Заключение**: Параллельное умножение матриц демонстрирует значительное ускорение для больших матриц, однако требует тщательного выбора количества потоков и учета накладных расходов. Реализованный алгоритм эффективно распределяет вычислительную нагрузку и показывает хорошую масштабируемость для задач достаточного объема.
# Ссылка на видео:
[Видео](https://rutube.ru/video/private/84f875263c0ef2170d2a840e46f2fb71/?p=uizyfNcxTmOGglnnXwggSA)

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB