forked from Alexey/DAS_2024_1
Merge pull request 'kashin_maxim_lab_6' (#126) from kashin_maxim_lab_6 into main
Reviewed-on: Alexey/DAS_2024_1#126
This commit is contained in:
commit
77bd667129
57
kashin_maxim_lab_6/main.py
Normal file
57
kashin_maxim_lab_6/main.py
Normal file
@ -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)
|
72
kashin_maxim_lab_6/readme.md
Normal file
72
kashin_maxim_lab_6/readme.md
Normal file
@ -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)
|
Loading…
Reference in New Issue
Block a user