forked from Alexey/DAS_2024_1
89 lines
4.0 KiB
Python
89 lines
4.0 KiB
Python
import random as rnd
|
||
import time
|
||
from multiprocessing import Pool
|
||
|
||
# Инициализируем матрицу результата нулями (так легче!)
|
||
base_matrix = [[0 for i in range(500)] for j in range(500)]
|
||
|
||
# Функция для генерации квадратной матрицы заданного размера со случайными значениями от 0 до 100
|
||
def generateMatrixWithSize(size):
|
||
return [[rnd.randint(0, 100) for i in range(size)] for j in range(size)]
|
||
|
||
# Функция для вывода матрицы на экран
|
||
def printMatrix(matrix):
|
||
for row in matrix:
|
||
print(*row, sep="\t")
|
||
|
||
# Функция для перемножения матриц без использования потоков (стандартный алгоритм)
|
||
def multiplyMatrixOGWay(matrix1, matrix2):
|
||
l1 = len(matrix1)
|
||
l2 = len(matrix2)
|
||
global base_matrix # Используем глобальную переменную для хранения результата
|
||
result = base_matrix
|
||
for i in range(l1):
|
||
for j in range(l2):
|
||
for k in range(l2):
|
||
result[i][j] += matrix1[i][k] * matrix2[k][j]
|
||
|
||
return result
|
||
|
||
|
||
# Функция для перемножения части матриц в отдельном процессе (worker для Pool)
|
||
def matrixMultiplyByOneProcess(args):
|
||
matrix1_slice, matrix2, start_i, end_i = args # Распаковываем аргументы
|
||
global base_matrix # Используем глобальную переменную для хранения результата
|
||
|
||
# Локальная ссылка для удобства
|
||
result = base_matrix
|
||
|
||
for i in range(end_i-start_i):
|
||
for j in range(len(matrix2[0])):
|
||
for k in range(len(matrix2)):
|
||
result[i + start_i][j] += matrix1_slice[i][k] * matrix2[k][j]
|
||
|
||
|
||
# Функция для параллельного перемножения матриц с использованием процессов
|
||
def matrixMultiplyWithProcesses(matrix1, matrix2, process_count):
|
||
l1 = len(matrix1)
|
||
|
||
# Расчет количества строк на каждый процесс
|
||
chunk_size = l1 // process_count
|
||
remainder = l1 % process_count
|
||
|
||
args = []
|
||
start_i = 0
|
||
for i in range(process_count):
|
||
end_i = start_i + chunk_size + (1 if i < remainder else 0)
|
||
args.append((matrix1[start_i:end_i], matrix2, start_i, end_i))
|
||
start_i = end_i
|
||
|
||
# Создание пула процессов и выполнение расчета
|
||
with Pool(processes=process_count) as pool:
|
||
pool.map(matrixMultiplyByOneProcess, args)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
|
||
matrix_sizes = [100, 300, 500]
|
||
num_processes = [1, 5, 10]
|
||
|
||
for size in matrix_sizes:
|
||
matrix1 = generateMatrixWithSize(size)
|
||
matrix2 = generateMatrixWithSize(size)
|
||
|
||
# Замер времени для стандартного умножения
|
||
base_matrix = [[0 for i in range(size)] for j in range(size)] # Очищаем перед каждым запуском.
|
||
start_time = time.time()
|
||
multiplyMatrixOGWay(matrix1, matrix2)
|
||
end_time = time.time()
|
||
print(f"Обычный режим. Размер матрицы: {size}. {end_time - start_time} сек.")
|
||
|
||
# Замер времени для параллельного умножения с разным количеством процессов
|
||
for processes in num_processes:
|
||
base_matrix = [[0 for i in range(size)] for j in range(size)] # Очищаем перед каждым запуском.
|
||
start_time = time.time()
|
||
matrixMultiplyWithProcesses(matrix1, matrix2, processes)
|
||
end_time = time.time()
|
||
print(f"Параллельный режим. Размер матрицы: {size}. Количество процессов: {processes}. {end_time - start_time} сек.")
|
||
|
||
print("\n\n") |