108 lines
3.0 KiB
Python
108 lines
3.0 KiB
Python
|
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()
|