diff --git a/ismailov_rovshan_lab_6/README.md b/ismailov_rovshan_lab_6/README.md new file mode 100644 index 0000000..b72e193 --- /dev/null +++ b/ismailov_rovshan_lab_6/README.md @@ -0,0 +1,20 @@ +# Лабораторная работа №6 - Параллельный поиск значения детерминанта матрицы +## ПИбд-42 || Исмаилов Ровшан + +### Цель лабораторной работы +Изучение принципов работы праллельных вычислений. + +### Описание: +Реализован механизм параллельного вычисления детерминанта матриц с настройкой количества потоков, включая использование одного потока для обычного (последовательного) вычисления. Механизм был протестирован на матрицах размером 9x9, 10x10 и 11x11. Для каждого вычисления были произведены замеры времени, проведен анализ результатов и сделаны соответствующие выводы. + +### Результаты: +![Изображение 1](./result.png) + +### Выводы: +При параллельном вычислении детерминанта основная цель — сократить время выполнения за счет увеличения числа потоков. Этот подход действительно дает положительные результаты, но существуют некоторые особенности. +Анализ показал, что для вычисления детерминанта матрицы в одном потоке понадобилось 206 секунды, в то время как при использовании 8 потоков время снизилось до 99 секунд, что означает более чем двукратное ускорение вычислений. +Однако для небольших задач увеличение числа потоков может привести к дополнительным затратам. Управление многопоточностью требует ресурсов, и в таких случаях выгода от параллелизма может нивелироваться. Поэтому решение о разбиении задачи на потоки должно зависеть от ее масштаба. +Кроме того, важно правильно выбрать оптимальное количество потоков. Увеличение их числа не всегда означает улучшение производительности, так как на управление потоками также расходуются ресурсы. + +### Видео с демонстрацией работы: +https://cloud.mail.ru/public/3jaE/Mrkthmwrv \ No newline at end of file diff --git a/ismailov_rovshan_lab_6/main.py b/ismailov_rovshan_lab_6/main.py new file mode 100644 index 0000000..ca51bcb --- /dev/null +++ b/ismailov_rovshan_lab_6/main.py @@ -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() \ No newline at end of file diff --git a/ismailov_rovshan_lab_6/result.png b/ismailov_rovshan_lab_6/result.png new file mode 100644 index 0000000..886dfe7 Binary files /dev/null and b/ismailov_rovshan_lab_6/result.png differ