62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
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 потоков)
|