From 6baa4ddabe30af6764d8cc32dd002843e2767f60 Mon Sep 17 00:00:00 2001 From: maksim Date: Sun, 27 Oct 2024 20:01:01 +0400 Subject: [PATCH] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kashin_maxim_lab_6/main.py | 57 ++++++++++++++++++++++++++++ kashin_maxim_lab_6/readme.md | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 kashin_maxim_lab_6/main.py create mode 100644 kashin_maxim_lab_6/readme.md diff --git a/kashin_maxim_lab_6/main.py b/kashin_maxim_lab_6/main.py new file mode 100644 index 0000000..60f1789 --- /dev/null +++ b/kashin_maxim_lab_6/main.py @@ -0,0 +1,57 @@ +import numpy as np +from multiprocessing import Pool +import time +import argparse + + +def determinant_block(matrix_block): + """Вычисляет детерминант блока матрицы.""" + return np.linalg.det(matrix_block) + + +def determinant_parallel(matrix, num_processes): + """Вычисляет детерминант матрицы параллельно.""" + size = matrix.shape[0] + step = size // num_processes + + # Обработка случаев, когда размер матрицы не делится на число процессов + blocks = [] + for i in range(num_processes): + start_row = i * step + end_row = start_row + step if i < num_processes - 1 else size + blocks.append(matrix[start_row:end_row, start_row:end_row]) + + pool = Pool(processes=num_processes) + dets = pool.map(determinant_block, blocks) + pool.close() + pool.join() + + # Объединение детерминантов блоков + return np.prod(dets) + + +def benchmark(size, num_processes): + """Запускает бенчмарк для матрицы заданного размера и числа процессов.""" + matrix = np.random.rand(size, size) + + # Параллельное вычисление детерминанта + start = time.time() + det_parallel = determinant_parallel(matrix, num_processes) + end = time.time() + print(f"Матрица {size}x{size} с {num_processes} процессами заняла {end - start:.5f} сек (Параллельно)") + + # Последовательное вычисление детерминанта + start = time.time() + det_seq = determinant_block(matrix) + end = time.time() + print(f"Матрица {size}x{size} последовательный вычисление заняло {end - start:.5f} сек (Последовательно)") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Вычисление детерминанта с параллельной обработкой") + parser.add_argument("--processes", type=int, default=4) + args = parser.parse_args() + + sizes = [100, 300, 500] + for size in sizes: + benchmark(size, args.processes) diff --git a/kashin_maxim_lab_6/readme.md b/kashin_maxim_lab_6/readme.md new file mode 100644 index 0000000..84d94fe --- /dev/null +++ b/kashin_maxim_lab_6/readme.md @@ -0,0 +1,72 @@ +# Кашин Максим ПИбд-42 + +# Отчет по вычислению детерминанта матрицы + +## Описание + +В данной лабораторной работе реализовано вычисление детерминанта квадратной матрицы двумя способами: последовательно и параллельно. Для параллельного вычисления используется библиотека `multiprocessing` в Python. Программа позволяет задавать количество процессов, что позволяет наблюдать за изменением производительности при увеличении числа потоков. + +## Как работает код + +1. **Импорт библиотек**: + - `numpy` используется для работы с матрицами и вычисления детерминанта. + - `multiprocessing` позволяет создавать несколько процессов для параллельного вычисления. + - `time` используется для замера времени выполнения. + - `argparse` для обработки аргументов командной строки. + +2. **Функция `determinant_block(matrix_block)`**: + - Вычисляет детерминант переданного блока матрицы с помощью `numpy.linalg.det`. + +3. **Функция `determinant_parallel(matrix, num_processes)`**: + - Делит исходную матрицу на блоки, каждый из которых передается в отдельный процесс для вычисления детерминанта. + - Возвращает произведение детерминантов блоков. + +4. **Функция `benchmark(size, num_processes)`**: + - Генерирует случайную матрицу заданного размера. + - Запускает параллельное и последовательное вычисление детерминанта, измеряя время выполнения и выводя результаты. + +5. **Основная часть программы**: + - Использует `argparse` для получения количества процессов. + - Запускает бенчмарки для матриц размером 100x100, 300x300 и 500x500. + +## Результаты + +В процессе тестирования были получены следующие результаты: + +### Сравнение времени выполнения: + +| Размер матрицы | Количество процессов | Время (сек. параллельно) | Время (сек. последовательно) | +|----------------|----------------------|---------------------------|-------------------------------| +| 100x100 | 1 | 0.52331 | 0.04900 | +| 300x300 | 1 | 0.51905 | 0.00700 | +| 500x500 | 1 | 0.53077 | 0.01000 | +| 100x100 | 2 | 0.49886 | 0.00299 | +| 300x300 | 2 | 0.87159 | 0.00799 | +| 500x500 | 2 | 1.25856 | 0.01200 | +| 100x100 | 4 | 0.59433 | 0.00152 | +| 300x300 | 4 | 0.56344 | 0.00700 | +| 500x500 | 4 | 1.51391 | 0.01600 | +| 100x100 | 8 | 0.87769 | 0.00200 | +| 300x300 | 8 | 0.80332 | 0.00600 | +| 500x500 | 8 | 0.81058 | 0.01700 | +| 100x100 | 16 | 1.58553 | 0.00300 | +| 300x300 | 16 | 1.44331 | 0.00900 | +| 500x500 | 16 | 1.48519 | 0.06000 | + +## Выводы + +1. **Производительность**: Параллельное вычисление показывает значительное замедление по сравнению с последовательным для малых матриц (например, 100x100). Это связано с накладными расходами на создание и управление процессами. + +2. **Эффективность**: С увеличением размеров матриц (300x300 и 500x500) время параллельного вычисления увеличивается, что указывает на неэффективность при использовании большого количества процессов. В некоторых случаях, например, для матрицы 500x500 с 4 и 8 процессами, время выполнения параллельного алгоритма оказывается больше, чем у последовательного. + +## Запуск + +Запустите программу с нужным числом процессов: + +``` +python main.py --processes <число процессов> +``` + + +## Ссылка на видео +[Видео-отчёт Кашин Максим ПИбд-42](https://disk.yandex.ru/i/0zlwA89Pk_5dXQ) \ No newline at end of file