ismailov_rovshan_lab_6 is ready #327
20
ismailov_rovshan_lab_6/README.md
Normal file
20
ismailov_rovshan_lab_6/README.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Лабораторная работа №6 - Параллельный поиск значения детерминанта матрицы
|
||||||
|
## ПИбд-42 || Исмаилов Ровшан
|
||||||
|
|
||||||
|
### Цель лабораторной работы
|
||||||
|
Изучение принципов работы праллельных вычислений.
|
||||||
|
|
||||||
|
### Описание:
|
||||||
|
Реализован механизм параллельного вычисления детерминанта матриц с настройкой количества потоков, включая использование одного потока для обычного (последовательного) вычисления. Механизм был протестирован на матрицах размером 9x9, 10x10 и 11x11. Для каждого вычисления были произведены замеры времени, проведен анализ результатов и сделаны соответствующие выводы.
|
||||||
|
|
||||||
|
### Результаты:
|
||||||
|
![Изображение 1](./result.png)
|
||||||
|
|
||||||
|
### Выводы:
|
||||||
|
При параллельном вычислении детерминанта основная цель — сократить время выполнения за счет увеличения числа потоков. Этот подход действительно дает положительные результаты, но существуют некоторые особенности.
|
||||||
|
Анализ показал, что для вычисления детерминанта матрицы в одном потоке понадобилось 206 секунды, в то время как при использовании 8 потоков время снизилось до 99 секунд, что означает более чем двукратное ускорение вычислений.
|
||||||
|
Однако для небольших задач увеличение числа потоков может привести к дополнительным затратам. Управление многопоточностью требует ресурсов, и в таких случаях выгода от параллелизма может нивелироваться. Поэтому решение о разбиении задачи на потоки должно зависеть от ее масштаба.
|
||||||
|
Кроме того, важно правильно выбрать оптимальное количество потоков. Увеличение их числа не всегда означает улучшение производительности, так как на управление потоками также расходуются ресурсы.
|
||||||
|
|
||||||
|
### Видео с демонстрацией работы:
|
||||||
|
https://cloud.mail.ru/public/3jaE/Mrkthmwrv
|
91
ismailov_rovshan_lab_6/main.py
Normal file
91
ismailov_rovshan_lab_6/main.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import random
|
||||||
|
import time
|
||||||
|
import multiprocessing
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
# Генерация матрицы
|
||||||
|
def generate_matrix(size):
|
||||||
|
return [[random.randint(0, 10) for _ in range(size)] for _ in range(size)]
|
||||||
|
|
||||||
|
|
||||||
|
# Вычисление детерминанта матрицы (рекурсивно)
|
||||||
|
def determinant(matrix):
|
||||||
|
size = len(matrix)
|
||||||
|
if size == 2:
|
||||||
|
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
|
||||||
|
|
||||||
|
det = 0
|
||||||
|
for col in range(size):
|
||||||
|
submatrix = [row[:col] + row[col + 1:] for row in matrix[1:]]
|
||||||
|
det += ((-1) ** col) * matrix[0][col] * determinant(submatrix)
|
||||||
|
return det
|
||||||
|
|
||||||
|
|
||||||
|
# Вычисление детерминанта параллельно
|
||||||
|
def parallel_determinant(matrix, num_processes):
|
||||||
|
size = len(matrix)
|
||||||
|
if size <= 2:
|
||||||
|
return determinant(matrix)
|
||||||
|
|
||||||
|
# Разбиение задачи по строкам на несколько потоков
|
||||||
|
chunk_size = size // num_processes
|
||||||
|
chunks = []
|
||||||
|
|
||||||
|
# Создание задач для потоков
|
||||||
|
for i in range(num_processes):
|
||||||
|
start_row = i * chunk_size
|
||||||
|
end_row = (i + 1) * chunk_size if i < num_processes - 1 else size
|
||||||
|
chunks.append((matrix[start_row:end_row], i))
|
||||||
|
|
||||||
|
with multiprocessing.Pool(processes=num_processes) as pool:
|
||||||
|
results = pool.starmap(calculate_determinant_chunk, [(matrix, chunk[0], chunk[1]) for chunk in chunks])
|
||||||
|
|
||||||
|
det = sum(results)
|
||||||
|
return det
|
||||||
|
|
||||||
|
|
||||||
|
# Вычисление детерминанта для части матрицы в одном процессе
|
||||||
|
def calculate_determinant_chunk(matrix, chunk, chunk_index):
|
||||||
|
size = len(matrix)
|
||||||
|
det = 0
|
||||||
|
for row in chunk:
|
||||||
|
for col in range(size):
|
||||||
|
submatrix = [r[:col] + r[col + 1:] for r in matrix[1:]]
|
||||||
|
det += ((-1) ** (chunk_index + col)) * matrix[0][col] * determinant(submatrix)
|
||||||
|
return det
|
||||||
|
|
||||||
|
|
||||||
|
# Замер времени для параллельного вычисления детерминанта
|
||||||
|
def benchmark(size, num_processes=1):
|
||||||
|
matrix = generate_matrix(size)
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
parallel_determinant(matrix, num_processes)
|
||||||
|
par_time = time.time() - start_time
|
||||||
|
|
||||||
|
return par_time
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Размеры матриц
|
||||||
|
matrix_sizes = [9, 10, 11]
|
||||||
|
# Количество потоков
|
||||||
|
num_processes_list = [1, 2, 4, 6, 8]
|
||||||
|
# Таблица с бенчмарками
|
||||||
|
print("-*" * 40)
|
||||||
|
print(f"{'Количество потоков':<20}{'|9x9 (сек.)':<20}{'|10x10 (сек.)':<20}{'|11x11 (сек.)'}")
|
||||||
|
print("-*" * 40)
|
||||||
|
|
||||||
|
for num_processes in num_processes_list:
|
||||||
|
row = f"{num_processes:<20}"
|
||||||
|
|
||||||
|
for size in matrix_sizes:
|
||||||
|
par_time = benchmark(size, num_processes)
|
||||||
|
row += f"|{par_time:.4f}".ljust(20)
|
||||||
|
print(row)
|
||||||
|
print("-*" * 40)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
BIN
ismailov_rovshan_lab_6/result.png
Normal file
BIN
ismailov_rovshan_lab_6/result.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 108 KiB |
Loading…
Reference in New Issue
Block a user