agliullov_daniyar_lab_6 is ready #183
Binary file not shown.
After Width: | Height: | Size: 227 KiB |
86
agliullov_daniyar_lab_6/main.py
Normal file
86
agliullov_daniyar_lab_6/main.py
Normal file
@ -0,0 +1,86 @@
|
||||
import numpy as np
|
||||
import time
|
||||
from multiprocessing import Pool
|
||||
|
||||
np.seterr(over='ignore')
|
||||
|
||||
# Функция для вычисления детерминанта методом Гаусса
|
||||
def compute_determinant_gauss(mat):
|
||||
size = mat.shape[0]
|
||||
matrix_copy = mat.astype(float) # Копируем матрицу, чтобы не изменять исходную
|
||||
determinant = 1.0 # Начальное значение детерминанта
|
||||
|
||||
for k in range(size):
|
||||
# Находим максимальный элемент в текущем столбце для уменьшения ошибок округления
|
||||
max_index = np.argmax(np.abs(matrix_copy[k:size, k])) + k
|
||||
if matrix_copy[max_index, k] == 0:
|
||||
return 0 # Если на главной диагонали ноль, детерминант равен нулю
|
||||
# Меняем местами строки
|
||||
if max_index != k:
|
||||
matrix_copy[[k, max_index]] = matrix_copy[[max_index, k]]
|
||||
determinant *= -1 # Каждая перестановка меняет знак детерминанта
|
||||
# Обнуляем элементы ниже главной диагонали
|
||||
for m in range(k + 1, size):
|
||||
multiplier = matrix_copy[m, k] / matrix_copy[k, k]
|
||||
matrix_copy[m, k:] -= multiplier * matrix_copy[k, k:]
|
||||
|
||||
# Произведение элементов на главной диагонали
|
||||
for j in range(size):
|
||||
determinant *= matrix_copy[j, j]
|
||||
return determinant
|
||||
|
||||
# Функция для параллельного вычисления детерминанта
|
||||
def parallel_worker(index_range, mat):
|
||||
size = mat.shape[0]
|
||||
matrix_copy = mat.astype(float)
|
||||
det = 1.0
|
||||
|
||||
for k in range(index_range[0], index_range[1]):
|
||||
max_index = np.argmax(np.abs(matrix_copy[k:size, k])) + k
|
||||
if matrix_copy[max_index, k] == 0:
|
||||
return 0
|
||||
if max_index != k:
|
||||
matrix_copy[[k, max_index]] = matrix_copy[[max_index, k]]
|
||||
det *= -1
|
||||
for m in range(k + 1, size):
|
||||
multiplier = matrix_copy[m, k] / matrix_copy[k, k]
|
||||
matrix_copy[m, k:] -= multiplier * matrix_copy[k, k:]
|
||||
return det
|
||||
|
||||
# Функция для параллельного вычисления детерминанта
|
||||
def compute_parallel_determinant(mat, num_workers):
|
||||
size = mat.shape[0]
|
||||
block_size = size // num_workers
|
||||
ranges = [(i * block_size, (i + 1) * block_size) for i in range(num_workers)]
|
||||
|
||||
with Pool(processes=num_workers) as pool:
|
||||
results = pool.starmap(parallel_worker, [(block, mat) for block in ranges])
|
||||
|
||||
# Объединяем результаты
|
||||
total_determinant = sum(results)
|
||||
return total_determinant
|
||||
|
||||
# Функция для запуска тестов производительности
|
||||
def execute_benchmarks():
|
||||
sizes = [100, 300, 500, 1000, 1200] # Размеры матриц
|
||||
for size in sizes:
|
||||
random_matrix = np.random.rand(size, size) # Генерация случайной матрицы
|
||||
print(f"--- Тест производительности для матрицы {size}x{size} ---")
|
||||
|
||||
# Последовательное вычисление детерминанта
|
||||
start_time = time.time()
|
||||
sequential_det = compute_determinant_gauss(random_matrix)
|
||||
seq_duration = time.time() - start_time
|
||||
print(f"Время последовательного вычисления для {size}x{size}: {seq_duration:.4f} секунд")
|
||||
|
||||
# Параллельное вычисление с различным количеством процессов
|
||||
for workers in [1, 2, 4, 6, 8, 12, 16]:
|
||||
start_time = time.time()
|
||||
parallel_det = compute_parallel_determinant(random_matrix, workers)
|
||||
par_duration = time.time() - start_time
|
||||
speedup_ratio = seq_duration / par_duration if par_duration > 0 else 0
|
||||
print(f"Параллельное время с {workers} процессами: {par_duration:.4f} секунд, Ускорение: {speedup_ratio:.2f}")
|
||||
|
||||
# Запуск тестов производительности
|
||||
if __name__ == '__main__':
|
||||
execute_benchmarks()
|
15
agliullov_daniyar_lab_6/readme.md
Normal file
15
agliullov_daniyar_lab_6/readme.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Аглиуллов Данияр ИСЭбд-41
|
||||
# Лабораторная работа №6
|
||||
|
||||
Для повышения производительности при вычислении детерминанта для больших матриц была добавлена возможность параллельной обработки с использованием библиотеки multiprocessing. Это позволило значительно ускорить вычисления за счет распределения нагрузки между несколькими процессами.
|
||||
|
||||
Результаты тестов:
|
||||
![изображение 1](../Screenshots/1.png)
|
||||
|
||||
Сравнение производительности:
|
||||
|
||||
• В тестах на матрицах размером 100x100, 300x300 и 500x500 было замечено, что параллельный алгоритм демонстрирует значительное сокращение времени выполнения по сравнению с обычным алгоритмом, особенно на больших матрицах. Это подтверждает эффективность использования многопоточности для задач, требующих больших вычислительных ресурсов.
|
||||
|
||||
• На малых размерах матриц (например, 100x100) преимущество было за последовательным умножением матрицы из-за накладных расходов на создание пула потоков. Однако при увеличении размера матрицы (300x300 и 500x500) преимущества параллельного подхода становились более очевидными.
|
||||
• При превышении количества физических потоков процессора, производительность понижается за счет смены контекста при переключении виртуальных потоков на одном ядре
|
||||
|
Loading…
Reference in New Issue
Block a user