Merge pull request 'ismailov_rovshan_lab_6 is ready' () from ismailov_rovshan_lab_6 into main

Reviewed-on: 
This commit is contained in:
Alexey 2024-12-15 14:48:54 +04:00
commit 9495f5cd12
3 changed files with 111 additions and 0 deletions
ismailov_rovshan_lab_6

View File

@ -0,0 +1,20 @@
# Лабораторная работа №6 - Параллельный поиск значения детерминанта матрицы
## ПИбд-42 || Исмаилов Ровшан
### Цель лабораторной работы
Изучение принципов работы праллельных вычислений.
### Описание:
Реализован механизм параллельного вычисления детерминанта матриц с настройкой количества потоков, включая использование одного потока для обычного (последовательного) вычисления. Механизм был протестирован на матрицах размером 9x9, 10x10 и 11x11. Для каждого вычисления были произведены замеры времени, проведен анализ результатов и сделаны соответствующие выводы.
### Результаты:
![Изображение 1](./result.png)
### Выводы:
При параллельном вычислении детерминанта основная цель — сократить время выполнения за счет увеличения числа потоков. Этот подход действительно дает положительные результаты, но существуют некоторые особенности.
Анализ показал, что для вычисления детерминанта матрицы в одном потоке понадобилось 206 секунды, в то время как при использовании 8 потоков время снизилось до 99 секунд, что означает более чем двукратное ускорение вычислений.
Однако для небольших задач увеличение числа потоков может привести к дополнительным затратам. Управление многопоточностью требует ресурсов, и в таких случаях выгода от параллелизма может нивелироваться. Поэтому решение о разбиении задачи на потоки должно зависеть от ее масштаба.
Кроме того, важно правильно выбрать оптимальное количество потоков. Увеличение их числа не всегда означает улучшение производительности, так как на управление потоками также расходуются ресурсы.
### Видео с демонстрацией работы:
https://cloud.mail.ru/public/3jaE/Mrkthmwrv

View 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()

Binary file not shown.

After

(image error) Size: 108 KiB