putilin_pavel_lab_5

This commit is contained in:
Pavel 2024-12-05 17:40:44 +04:00
parent 219c77a03f
commit 8ed34545c0
2 changed files with 145 additions and 0 deletions

View File

@ -0,0 +1,37 @@
# Лабораторная работа №5: Вспоминаем математику или параллельное перемножение матриц
## Задание
Реализовать умножение двух квадратных матриц двумя способами: обычным и параллельным.
В параллельном алгоритме предусмотреть возможность задания количества потоков.
Каждый поток должен выполнять умножение матрицы в своей зоне ответственности.
### Требования:
1. Обычное умножение матриц.
2. Параллельное умножение с ручным заданием количества потоков.
3. Бенчмаркинг для матриц размером 100x100, 300x300 и 500x500.
## Структура проекта
Проект реализован в одном файле `main.py`. В нем содержатся:
- Обычное умножение матриц.
- Параллельное умножение с использованием многозадачности.
- Генерация случайных матриц для тестирования.
- Бенчмаркинг для проверки времени выполнения обоих алгоритмов.
- Тесты для проверки корректности умножения.
## Видео
https://cloud.mail.ru/public/Wzc4/FZCUnh5mk
## Заключение
В ходе лабораторной работы были реализованы два алгоритма умножения матриц:
обычный и параллельный. Параллельное умножение показало
значительное ускорение при больших матрицах.
Ожидаемо, для маленьких матриц разница
в производительности между алгоритмами была незначительной.
Параллельное умножение эффективно использует многозадачность
для уменьшения времени выполнения на крупных матрицах.

108
putilin_pavel_lab_5/main.py Normal file
View File

@ -0,0 +1,108 @@
import random
import time
import multiprocessing
def matrix_multiply(A, B):
rows_A = len(A)
cols_A = len(A[0])
cols_B = len(B[0])
if len(B) != cols_A:
raise ValueError("Количество столбцов первой матрицы должно совпадать с количеством строк второй матрицы.")
result = [[0] * cols_B for _ in range(rows_A)]
for i in range(rows_A):
for j in range(cols_B):
for k in range(cols_A):
result[i][j] += A[i][k] * B[k][j]
return result
def parallel_multiply_worker(A, B, result, row_index, cols_A, cols_B):
for j in range(cols_B):
result[row_index][j] = sum(A[row_index][k] * B[k][j] for k in range(cols_A))
def parallel_matrix_multiply(A, B, num_threads):
rows_A = len(A)
cols_A = len(A[0])
cols_B = len(B[0])
if len(B) != cols_A:
raise ValueError("Количество столбцов первой матрицы должно совпадать с количеством строк второй матрицы.")
result = [[0] * cols_B for _ in range(rows_A)]
processes = []
for i in range(rows_A):
p = multiprocessing.Process(target=parallel_multiply_worker, args=(A, B, result, i, cols_A, cols_B))
processes.append(p)
p.start()
for p in processes:
p.join()
return result
def generate_matrix(rows, cols):
return [[random.randint(1, 10) for _ in range(cols)] for _ in range(rows)]
def benchmark_matrix_multiplication():
sizes = [100, 300, 500]
num_threads = 4
for size in sizes:
print(f"Размер матрицы: {size}x{size}")
A = generate_matrix(size, size)
B = generate_matrix(size, size)
start_time = time.time()
matrix_multiply(A, B)
end_time = time.time()
print(f"Обычное умножение: {end_time - start_time:.4f} секунд")
start_time = time.time()
parallel_matrix_multiply(A, B, num_threads)
end_time = time.time()
print(f"Параллельное умножение: {end_time - start_time:.4f} секунд")
def test_matrix_multiply():
A = [
[1, 2],
[3, 4]
]
B = [
[5, 6],
[7, 8]
]
expected_result = [
[19, 22],
[43, 50]
]
result = matrix_multiply(A, B)
assert result == expected_result, f"Тест не пройден! Результат: {result}"
try:
A = [
[1, 2]
]
B = [
[5, 6],
[7, 8]
]
matrix_multiply(A, B)
except ValueError:
print("Ошибка умножения матриц с несовпадающими размерами (ожидаемо).")
if __name__ == "__main__":
print("Запуск тестов...")
test_matrix_multiply()
print("Тесты пройдены успешно!")
print("\nЗапуск бенчмаркинга...")
benchmark_matrix_multiplication()