From 239da31a0da59b1148c8d59479e4908b7f61cfb4 Mon Sep 17 00:00:00 2001 From: romai Date: Sun, 15 Dec 2024 06:47:19 +0400 Subject: [PATCH] ismailov_rovshan_lab_5 is ready --- ismailov_rovshan_lab_5/README.md | 17 +++++++++ ismailov_rovshan_lab_5/main.py | 59 ++++++++++++++++++++++++++++++ ismailov_rovshan_lab_5/result.png | Bin 0 -> 27781 bytes 3 files changed, 76 insertions(+) create mode 100644 ismailov_rovshan_lab_5/README.md create mode 100644 ismailov_rovshan_lab_5/main.py create mode 100644 ismailov_rovshan_lab_5/result.png diff --git a/ismailov_rovshan_lab_5/README.md b/ismailov_rovshan_lab_5/README.md new file mode 100644 index 0000000..9b4be6f --- /dev/null +++ b/ismailov_rovshan_lab_5/README.md @@ -0,0 +1,17 @@ +# Лабораторная работа №5 +## ПИбд-42 || Исмаилов Ровшан + +### Цель лабораторной работы +Изучение принципов работы праллельных вычислений. + +### Описание: +Был реализован механизм параллельного перемножения матриц 100x100, 300x300 и 500x500 с возможностью задания потоков, в том числе и 1 (последовательное перемножение). Были сделаны замеры времени для каждого вычисления, проведен анализ и сделаны выводы. + +### Результаты: +![Изображение 1](./result.png) + +### Выводы: +При использовании параллельного умножения матриц основной целью является сокращение времени вычислений за счет увеличения количества потоков, что дает ощутимый эффект для больших матриц. Однако это оправдано только в том случае, если затраты на настройку многопоточности не перевешивают преимущества параллельной обработки: для небольших задач, таких как умножение матриц 100x100, заметного улучшения времени не наблюдается, а значит, этот метод неэффективен. Кроме того, существует ограничение, заключающееся в том, что добавление новых потоков не приводит к увеличению скорости. Исходя из этого, было определено оптимальное количество потоков для данной задачи. + +### Видео с демонстрацией работы: +https://cloud.mail.ru/public/AfQo/nnejh3xt2 \ No newline at end of file diff --git a/ismailov_rovshan_lab_5/main.py b/ismailov_rovshan_lab_5/main.py new file mode 100644 index 0000000..3fb87e3 --- /dev/null +++ b/ismailov_rovshan_lab_5/main.py @@ -0,0 +1,59 @@ +import random +import time +import multiprocessing +import numpy as np + +def create_random_matrix(size): + return [[random.randint(0, 10) for _ in range(size)] for _ in range(size)] + +# Функция для умножения одной строки матрицы +def process_row(i, A, B, result): + size = len(A) + for j in range(size): + for k in range(size): + result[i][j] += A[i][k] * B[k][j] + + +# Функция для параллельного умножения матриц с использованием multiprocessing +def multiply_matrices_in_parallel(A, B, num_processes): + size = len(A) + result = [[0] * size for _ in range(size)] + + with multiprocessing.Pool(processes=num_processes) as pool: + pool.starmap(process_row, [(i, A, B, result) for i in range(size)]) + + return result + + +# Функция для измерения времени выполнения умножения матриц +def measure_execution_time(size, num_processes=1): + A = create_random_matrix(size) + B = create_random_matrix(size) + + start_time = time.time() + multiply_matrices_in_parallel(A, B, num_processes) + elapsed_time = time.time() - start_time + + return elapsed_time + +def main(): + matrix_sizes = [100, 300, 500] + process_count_options = [1, 2, 4, 6, 8] + + print("-*" * 40) + print(f"{'Количество потоков':<20}{'|100x100 (сек.)':<20}{'|300x300 (сек.)':<20}{'|500x500 (сек.)'}") + print("-*" * 40) + + # Запуск тестов для разных значений числа процессов + for num_processes in process_count_options: + row = f"{num_processes:<20}" + + for size in matrix_sizes: + par_time = measure_execution_time(size, num_processes) + row += f"|{par_time:.4f}".ljust(20) + print(row) + print("-*" * 40) + + +if __name__ == "__main__": + main() diff --git a/ismailov_rovshan_lab_5/result.png b/ismailov_rovshan_lab_5/result.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd995c7017dfd306bad7ef767c7183b2c4a73d8 GIT binary patch literal 27781 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 DsIJO! literal 0 HcmV?d00001