diff --git a/shadaev_anton_lab_5/README.md b/shadaev_anton_lab_5/README.md new file mode 100644 index 0000000..7dc101f --- /dev/null +++ b/shadaev_anton_lab_5/README.md @@ -0,0 +1,34 @@ +# Лабораторная работа №5 - Параллельное умножение матриц +Цель: +1. Реализовать алгоритм последовательного умножения матриц +2. Реализовать алгоритм параллельного умножения матриц + +## Запуск +Запускаем скрипт `main.py`, вывод будет консольным. + +## Код: +Последовательное умножение: + +![img.png](screenshots/img.png) + +Параллельное умножение: + +![img_2.png](screenshots/img_2.png) + +![img_3.png](screenshots/img_3.png) + +Тесты: + +![img_4.png](screenshots/img_4.png) + +# Работа программы + +Вывод: + +![img_5.png](screenshots/img_5.png) + +Таким образом, параллельное умножение дало преимущество при переменожении матриц большей размерности, +а на матрицах меньших размерностей не давало никаких преимуществ, а даже, наоборот, проигрывало последовательному перемножению. +Это связано с тем, что больше времени ушло на переключение между ядрами процессора. + +Видео: https://youtu.be/f4ayPI423n0 diff --git a/shadaev_anton_lab_5/main.py b/shadaev_anton_lab_5/main.py new file mode 100644 index 0000000..d56a470 --- /dev/null +++ b/shadaev_anton_lab_5/main.py @@ -0,0 +1,73 @@ +import numpy as np +import time +import multiprocessing + + +def sequential_matrix_multiply(matrix_a, matrix_b): + result = np.zeros((len(matrix_a), len(matrix_b[0]))) + for i in range(len(matrix_a)): + for j in range(len(matrix_b[0])): + for k in range(len(matrix_b)): + result[i][j] += matrix_a[i][k] * matrix_b[k][j] + return result + + +def parallel_matrix_multiply_worker(args): + matrix_a, matrix_b, row_start, row_end, result = args + local_result = np.zeros((row_end - row_start, len(matrix_b[0]))) + for i in range(row_start, row_end): + for j in range(len(matrix_b[0])): + for k in range(len(matrix_b)): + local_result[i - row_start][j] += matrix_a[i][k] * matrix_b[k][j] + result.extend(local_result) + + +def parallel_matrix_multiply(matrix_a, matrix_b, num_processes=2): + num_rows_a = len(matrix_a) + chunk_size = num_rows_a // num_processes + processes = [] + manager = multiprocessing.Manager() + result = manager.list() + + for i in range(num_processes): + row_start = i * chunk_size + row_end = (i + 1) * chunk_size if i < num_processes - 1 else num_rows_a + process_args = (matrix_a, matrix_b, row_start, row_end, result) + process = multiprocessing.Process(target=parallel_matrix_multiply_worker, args=(process_args,)) + processes.append(process) + + for process in processes: + process.start() + + for process in processes: + process.join() + + return np.vstack(result) + + +def run_test(matrix_size, num_processes=2): + matrix_a = np.random.rand(matrix_size, matrix_size) + matrix_b = np.random.rand(matrix_size, matrix_size) + + start_time = time.time() + result_sequential = sequential_matrix_multiply(matrix_a, matrix_b) + sequential_time = time.time() - start_time + print(f"Последовательноe умножение заняло ({matrix_size}x{matrix_size}): {sequential_time} секунд") + + start_time = time.time() + result_parallel = parallel_matrix_multiply(matrix_a, matrix_b, num_processes) + parallel_time = time.time() - start_time + print( + f"Параллельное умножение матрицы ({matrix_size}x{matrix_size}) с {num_processes} потоками заняло: {parallel_time} секунд") + print("========================================") + +# Тесты для матриц размером 100x100, 300x300 и 500x500 с разным числом процессов + +# Бенчмарки для матриц размером 100, 300, 500 строк +if __name__ == '__main__': + run_test(100, num_processes=2) + run_test(100, num_processes=4) + run_test(300, num_processes=2) + run_test(300, num_processes=4) + run_test(500, num_processes=2) + run_test(500, num_processes=4) \ No newline at end of file diff --git a/shadaev_anton_lab_5/screenshots/img.png b/shadaev_anton_lab_5/screenshots/img.png new file mode 100644 index 0000000..e9b4608 Binary files /dev/null and b/shadaev_anton_lab_5/screenshots/img.png differ diff --git a/shadaev_anton_lab_5/screenshots/img_1.png b/shadaev_anton_lab_5/screenshots/img_1.png new file mode 100644 index 0000000..63b7d91 Binary files /dev/null and b/shadaev_anton_lab_5/screenshots/img_1.png differ diff --git a/shadaev_anton_lab_5/screenshots/img_2.png b/shadaev_anton_lab_5/screenshots/img_2.png new file mode 100644 index 0000000..63b7d91 Binary files /dev/null and b/shadaev_anton_lab_5/screenshots/img_2.png differ diff --git a/shadaev_anton_lab_5/screenshots/img_3.png b/shadaev_anton_lab_5/screenshots/img_3.png new file mode 100644 index 0000000..f5af8ec Binary files /dev/null and b/shadaev_anton_lab_5/screenshots/img_3.png differ diff --git a/shadaev_anton_lab_5/screenshots/img_4.png b/shadaev_anton_lab_5/screenshots/img_4.png new file mode 100644 index 0000000..89f8a1d Binary files /dev/null and b/shadaev_anton_lab_5/screenshots/img_4.png differ diff --git a/shadaev_anton_lab_5/screenshots/img_5.png b/shadaev_anton_lab_5/screenshots/img_5.png new file mode 100644 index 0000000..42b52e0 Binary files /dev/null and b/shadaev_anton_lab_5/screenshots/img_5.png differ