Merge pull request 'novopolcev_alexander_lab_5' (#368) from novopolcev_alexander_lab_5_fix into main
Reviewed-on: #368
This commit is contained in:
commit
0055e97ec1
30
novopolcev_alexander_lab_5/README.md
Normal file
30
novopolcev_alexander_lab_5/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Лабораторная работа №5 - Параллельное умножение матриц
|
||||
|
||||
## Задание
|
||||
|
||||
|
||||
* Кратко: реализовать умножение двух больших квадратных матриц.
|
||||
|
||||
* Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности.
|
||||
|
||||
## Работа программы:
|
||||
|
||||
1. Генерируются случайные матрицы A и B заданных размеров.
|
||||
|
||||
2. multiply_matrices_sequential(A, B) умножает две матрицы A и B последовательно, используя вложенные циклы для вычисления элементов результирующей матрицы C.
|
||||
|
||||
3. multiply_matrices_parallel(A, B, num_workers) выполняет параллельное умножение матриц с использованием пула процессов.
|
||||
|
||||
4. benchmark(matrix_size, num_workers) Измеряет время выполнения операций умножения. И выводит результат в консоль.
|
||||
|
||||
### Результат:
|
||||
|
||||
![](result.jpg "")
|
||||
|
||||
### Вывод:
|
||||
|
||||
При работе с большими матрицами параллельная обработка обычно оказывается эффективнее последовательной благодаря распределению вычислительной нагрузки между несколькими процессорами. Однако при обработке малых матриц затраты на организацию и управление параллельными потоками могут превысить выигрыш от их использования, и тогда последовательная обработка окажется быстрее.
|
||||
|
||||
|
||||
# Видео
|
||||
https://disk.yandex.ru/i/MUL1RGOHfue8wQ
|
61
novopolcev_alexander_lab_5/main.py
Normal file
61
novopolcev_alexander_lab_5/main.py
Normal file
@ -0,0 +1,61 @@
|
||||
import numpy as np
|
||||
import time
|
||||
from multiprocessing import Pool
|
||||
|
||||
def multiply_matrices_sequential(A, B):
|
||||
"""Последовательное умножение матриц."""
|
||||
n = A.shape[0]
|
||||
C = np.zeros((n, n))
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
C[i][j] = np.dot(A[i], B[:, j]) # Используем векторизированное умножение для повышения производительности
|
||||
return C
|
||||
|
||||
def worker(args):
|
||||
"""Функция для параллельного умножения матриц, которая обрабатывает строки."""
|
||||
A, B, row_indices = args
|
||||
C_part = np.zeros((len(row_indices), B.shape[1]))
|
||||
|
||||
for idx, i in enumerate(row_indices):
|
||||
C_part[idx] = np.dot(A[i], B)
|
||||
|
||||
return C_part
|
||||
|
||||
def multiply_matrices_parallel(A, B, num_workers):
|
||||
"""Параллельное умножение матриц."""
|
||||
n = A.shape[0]
|
||||
C = np.zeros((n, n))
|
||||
row_indices = np.array_split(range(n), num_workers)
|
||||
|
||||
with Pool(processes=num_workers) as pool:
|
||||
results = pool.map(worker, [(A, B, idx) for idx in row_indices])
|
||||
|
||||
# Объединяем результаты
|
||||
for i, result in enumerate(results):
|
||||
C[i * len(result): (i + 1) * len(result)] = result
|
||||
|
||||
return C
|
||||
|
||||
def benchmark(matrix_size, num_workers):
|
||||
# Генерация случайных матриц
|
||||
A = np.random.rand(matrix_size, matrix_size)
|
||||
B = np.random.rand(matrix_size, matrix_size)
|
||||
|
||||
start_time = time.time()
|
||||
if num_workers == 1:
|
||||
C = multiply_matrices_sequential(A, B)
|
||||
else:
|
||||
C = multiply_matrices_parallel(A, B, num_workers)
|
||||
end_time = time.time()
|
||||
|
||||
method = "последовательное" if num_workers == 1 else f"параллельное с {num_workers} потоками"
|
||||
print(f"{method.capitalize()} умножение матриц {matrix_size}x{matrix_size}: {end_time - start_time:.6f} сек")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Запуск бенчмарков
|
||||
sizes = [100, 300, 500]
|
||||
for size in sizes:
|
||||
print(f"\nБенчмарк для матриц размером {size}x{size}:")
|
||||
benchmark(size, 1) # Последовательный
|
||||
benchmark(size, 4) # Параллельный (4 потока)
|
||||
benchmark(size, 8) # Параллельный (8 потоков)
|
BIN
novopolcev_alexander_lab_5/result.jpg
Normal file
BIN
novopolcev_alexander_lab_5/result.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
Loading…
Reference in New Issue
Block a user