Compare commits

..

1 Commits

Author SHA1 Message Date
Darya
4e19fb8cd0 agliullov_daniyar_lab_6 2024-11-13 19:59:58 +04:00
3 changed files with 101 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

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

View File

@ -0,0 +1,15 @@
# Аглиуллов Данияр ИСЭбд-41
# Лабораторная работа №6
Для повышения производительности при вычислении детерминанта для больших матриц была добавлена возможность параллельной обработки с использованием библиотеки multiprocessing. Это позволило значительно ускорить вычисления за счет распределения нагрузки между несколькими процессами.
Результаты тестов:
![изображение 1](../Screenshots/1.png)
Сравнение производительности:
В тестах на матрицах размером 100x100, 300x300 и 500x500 было замечено, что параллельный алгоритм демонстрирует значительное сокращение времени выполнения по сравнению с обычным алгоритмом, особенно на больших матрицах. Это подтверждает эффективность использования многопоточности для задач, требующих больших вычислительных ресурсов.
На малых размерах матриц (например, 100x100) преимущество было за последовательным умножением матрицы из-за накладных расходов на создание пула потоков. Однако при увеличении размера матрицы (300x300 и 500x500) преимущества параллельного подхода становились более очевидными.
• При превышении количества физических потоков процессора, производительность понижается за счет смены контекста при переключении виртуальных потоков на одном ядре