diff --git a/fadeeva_nastya_lab_5/README.md b/fadeeva_nastya_lab_5/README.md new file mode 100644 index 0000000..8cb002e --- /dev/null +++ b/fadeeva_nastya_lab_5/README.md @@ -0,0 +1,32 @@ +# Лабораторная работа №5 - Параллельное умножение матриц + +## Задание + +Требуется реализовать умножение двух больших квадратных матриц. +Надо сделать два алгоритма: обычный и параллельный. В параллельном алгоритме предусмотреть ручное задание количества потоков, каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности. + +## Описание работы + +Функция **benchmark** выполняет бенчмарк для матриц заданного размера. + +Генерируются две матрицы **matrix1** и **matrix2** заданного размера. + +После вызываются соответствующие методы для вычисления произведения матриц: ++ **multiply_matrices** - для обычного умножения ++ **multiply_matrices_parallel** - для параллельного умножения + +Прописываем бенчмарк (**benchmark**) для сравнения производительности, где генерируется две случайные матрицы заданного размера с помощью **random** и измеряется время выполнения каждого из методов с использованием функции **time.time()**. Функция **benchmark** вызывается трижды с различными размерами матриц (100x100, 300x300 и 500x500). + +### Результат работы программы + +![](RVIP_lab_5.png "") + +## Вывод + +Параллельный подход может быть более эффективным, чем последовательный, при работе с большими матрицами, поскольку он позволяет выполнять операции параллельно. +Это имеет смысл использовать при работе с крупными матрицами, где выигрыш от параллельных вычислений компенсирует затраты на управление потоками. +Однако для небольших матриц может быть более эффективным использовать обычное выполнение. + +# Видеозапись работы програмы + +https://vkvideo.ru/video186826232_456239556 diff --git a/fadeeva_nastya_lab_5/RVIP_lab_5.png b/fadeeva_nastya_lab_5/RVIP_lab_5.png new file mode 100644 index 0000000..e5deb22 Binary files /dev/null and b/fadeeva_nastya_lab_5/RVIP_lab_5.png differ diff --git a/fadeeva_nastya_lab_5/main.py b/fadeeva_nastya_lab_5/main.py new file mode 100644 index 0000000..2d31ef6 --- /dev/null +++ b/fadeeva_nastya_lab_5/main.py @@ -0,0 +1,54 @@ +import time +import numpy +import concurrent.futures + +# Функция для умножения матриц +def multiply_matrices(matrix1, matrix2): + return numpy.dot(matrix1, matrix2) + +# Параллельное умножение матриц +def multiply_matrices_parallel(matrix1, matrix2, num_threads): + result = numpy.zeros_like(matrix1) + chunk_size = matrix1.shape[0] // num_threads + + def multiply_chunk(start, end): + nonlocal result + for i in range(start, end): + result[i] = numpy.dot(matrix1[i], matrix2) + + with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor: + futures = [] + for i in range(0, matrix1.shape[0], chunk_size): + futures.append(executor.submit(multiply_chunk, i, i + chunk_size)) + + for future in concurrent.futures.as_completed(futures): + future.result() + + return result + +# Бенчмарк для сравнения производительности +def benchmark(matrix_size, num_threads_list=[1, 2, 4]): + # Генерация матриц + matrix1 = numpy.random.rand(matrix_size, matrix_size) + matrix2 = numpy.random.rand(matrix_size, matrix_size) + + # Бенчмарк для обычного умножения + start_time = time.time() + result = multiply_matrices(matrix1, matrix2) + end_time = time.time() + print(f"Размер матрицы {matrix_size}x{matrix_size}") + print(f"Последовательный: Время выполнения: {end_time - start_time:.6f} секунд") + + # Бенчмарк для параллельного умножения + for num_threads in num_threads_list: + start_time = time.time() + result_parallel = multiply_matrices_parallel(matrix1, matrix2, num_threads) + end_time = time.time() + print(f"Параллельный ({num_threads} поток): Время выполнения: {end_time - start_time:.6f} секунд") + + print() + +# Запуск бенчмарков +benchmark(100) +benchmark(300) +benchmark(500) \ No newline at end of file