import numpy as np from concurrent.futures import ProcessPoolExecutor import time #Функция умножения матриц def multi(A, B): n = len(A) k = len(B) C = np.zeros((n, n)) for i in range(n): for j in range(n): C[i][j] = sum(A[i][p] * B[p][j] for p in range(k)) return C # Функция последовательного умножения матриц def multi_sequential(A, B): n = len(A) C = np.zeros((n, n)) for i in range(n): for k in range(n): temp = A[i][k] for j in range(n): C[i][j] += temp * B[k][j] return C # Функция умножения матриц с numpy def multi_numpy(A, B): return np.dot(A, B) # Параллельное умножение матриц def multi_parallel(A, B, num_threads): n = len(A) C = np.zeros((n, n)) step = n // num_threads with ProcessPoolExecutor(max_workers=num_threads) as executor: futures = [] for i in range(num_threads): start_row = i * step end_row = (i + 1) * step if i != num_threads - 1 else n a_slice = A[:, i*step: (i+1)*step] b_slice = B[start_row:end_row] futures.append(executor.submit(multi, a_slice, b_slice)) for future in futures: C += future.result() return C # Пример использования if __name__ == "__main__": matrix_sizes = [100, 300, 500] num_threads = [2, 4, 5, 10] for n in matrix_sizes: A = np.random.rand(n, n) B = np.random.rand(n, n) # Умножение с numpy start_np = time.time() nump = multi_numpy(A, B) end_np = time.time() print(f'Умножение матриц {n}x{n} последовательно с numpy: {(end_np - start_np):.6f} с.') # Последовательное умножение start_seq = time.time() sequential = multi_sequential(A, B) end_seq = time.time() print(f'Умножение матриц {n}x{n} последовательно: {(end_seq - start_seq):.6f} с.') # Параллельное умножение for thread in num_threads: start_par = time.time() parallel = multi_parallel(A, B, thread) end_par = time.time() print(f'Умножение матриц {n}x{n} параллельно для {thread} потоков: {(end_par - start_par):.3f} с.') print('')