diff --git a/gusev_vladislav_lab_5/README.md b/gusev_vladislav_lab_5/README.md new file mode 100644 index 0000000..a79309e --- /dev/null +++ b/gusev_vladislav_lab_5/README.md @@ -0,0 +1,34 @@ +# Лабораторная работа №5 - Параллельное умножение матриц + +1) Реализовать алгоритм последовательного умножения матриц +2) Реализовать алгоритм параллельного умножения матриц + +# Как запустить +Выполняем файл gusev_vladislav_lab_5.py, решение будет в консоли. + + +# Методы: +Для последовательного умножения матриц используется следующий метод: + +![img.png](images%2Fimg.png) + +Для параллельного следующие методы: + +![img_1.png](images%2Fimg_1.png) + +Для тестов соответственно: + +![img_2.png](images%2Fimg_2.png) + + +# Работа программы + +Запускаем программу, получаем следующее: + +![img_3.png](images%2Fimg_3.png) + +Как видно по числам, параллельное умножение начало выигрывать начиная с 300x300 матриц, хотя на 100x100 проигрывало. + + + +Видео -> https://drive.google.com/file/d/1bs0kcvaYYQlKNle-tBUlr9mpYWTLyaRo/view?usp=sharing diff --git a/gusev_vladislav_lab_5/gusev_vladislav_lab_5.py b/gusev_vladislav_lab_5/gusev_vladislav_lab_5.py new file mode 100644 index 0000000..60c314b --- /dev/null +++ b/gusev_vladislav_lab_5/gusev_vladislav_lab_5.py @@ -0,0 +1,69 @@ +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} секунд") + +# Тесты для матриц размером 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) + + diff --git a/gusev_vladislav_lab_5/images/img.png b/gusev_vladislav_lab_5/images/img.png new file mode 100644 index 0000000..d1024df Binary files /dev/null and b/gusev_vladislav_lab_5/images/img.png differ diff --git a/gusev_vladislav_lab_5/images/img_1.png b/gusev_vladislav_lab_5/images/img_1.png new file mode 100644 index 0000000..860df59 Binary files /dev/null and b/gusev_vladislav_lab_5/images/img_1.png differ diff --git a/gusev_vladislav_lab_5/images/img_2.png b/gusev_vladislav_lab_5/images/img_2.png new file mode 100644 index 0000000..cd4f1d7 Binary files /dev/null and b/gusev_vladislav_lab_5/images/img_2.png differ diff --git a/gusev_vladislav_lab_5/images/img_3.png b/gusev_vladislav_lab_5/images/img_3.png new file mode 100644 index 0000000..4497906 Binary files /dev/null and b/gusev_vladislav_lab_5/images/img_3.png differ