DAS_2024_1/vaksman_valeria_lab_5/project/main.py

201 lines
7.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
import time
import threading
import copy
from multiprocessing import Pool
class Matrix:
def __init__(self) -> None:
self.matrix_100 = [[0] * 100 for _ in range(100)]
self.matrix_300 = [[0] * 300 for _ in range(300)]
self.matrix_500 = [[0] * 500 for _ in range(500)]
def str_matrix(self, type_list: str):
_str = ""
current_matrix = getattr(self, type_list)
for i in range(len(current_matrix)):
_str += "[ "
for j in range(len(current_matrix[0])):
_str += str(current_matrix[i][j]) + " "
_str += " ]\n"
return _str
# Глобальный объект класса для хранения результата работы потоков
result_matrix = copy.deepcopy(Matrix())
def init_matrix(matrix: Matrix, size: int):
support_list_main = []
for i in range(size):
support_list_column = []
for j in range(size):
support_list_column.append(random.randint(0, 10))
support_list_main.append(support_list_column)
if size == 100:
matrix.matrix_100 = support_list_main
elif size == 300:
matrix.matrix_300 = support_list_main
elif size == 500:
matrix.matrix_500 = support_list_main
# Простая функция перемножения матриц
def matrix_multiplication(matrix_first: Matrix, matrix_second: Matrix, type_matrix: str):
result_matrix = Matrix()
first_matrix = getattr(matrix_first, type_matrix)
second_matrix = getattr(matrix_second, type_matrix)
result = getattr(result_matrix, type_matrix)
for i in range(len(first_matrix)):
for j in range(len(second_matrix[0])):
for k in range(len(second_matrix)):
result[i][j] += first_matrix[i][k] * second_matrix[k][j]
return result_matrix
# Функция перемножения матриц в потоке
def matrix_multiplication_worker(args):
first_matrix, second_matrix, type_matrix, support_index, number_thread = args
global result_matrix
result = getattr(result_matrix, type_matrix)
for i in range(support_index[0], support_index[1]):
for j in range(len(second_matrix[0])):
for k in range(len(second_matrix)):
result[i][j] += first_matrix[i - support_index[0]][k] * second_matrix[k][j]
return f"Worker completed task of {number_thread}"
def matrix_multiplication_treads(matrix_first: Matrix, matrix_second: Matrix, type_matrix: str, count_thread: int):
first_matrix = getattr(matrix_first, type_matrix)
second_matrix = getattr(matrix_second, type_matrix)
# кол-во строк с конца
last_row = 0
if len(first_matrix) % count_thread == 0:
index_rows_by_thread = len(first_matrix) // count_thread
else:
index_rows_by_thread = len(first_matrix) // count_thread
last_row = len(first_matrix) % count_thread
# "распиливаем" первую матрицу на кол-во потоков. Результатом работы каждого потока будет являться часть перемноженной матрицы
support_matrix = []
for i in range(count_thread):
start_index = i * index_rows_by_thread
if i == count_thread - 1 and last_row > 0:
end_index = start_index + last_row
else:
end_index = start_index + index_rows_by_thread
support_matrix.append((first_matrix[start_index:end_index], second_matrix, type_matrix, [start_index, end_index], i))
# Попытка запуска нескольких ПОТОКОВ. Gil не дал получить выйгрыш, так как из-за его особенностей не давал параллельно вычислить перемножение двух матриц
# формируем пул потоков
# workers = [threading.Thread(target=matrix_multiplication_worker, args=(support_matrix[f], second_matrix, type_matrix, support_matrix_index[f], f), daemon=True) for f in range(count_thread)]
# for worker in workers:
# worker.start()
# for worker in workers:
# worker.join()
# Создание пула процессов и запуск параллельного выполнения
with Pool(processes=count_thread) as pool:
pool.map(matrix_multiplication_worker, support_matrix)
return "Done."
def run_program():
matrix_first = Matrix()
init_matrix(matrix_first, 100)
init_matrix(matrix_first, 300)
init_matrix(matrix_first, 500)
matrix_second = Matrix()
init_matrix(matrix_second, 100)
init_matrix(matrix_second, 300)
init_matrix(matrix_second, 500)
start_time = time.time()
matrix_multiplication(matrix_first, matrix_second, "matrix_100")
end_time = time.time()
print("Time 100x100: ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_100", 3)
end_time = time.time()
print("Time 100x100, 3 threads (processes): ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_100", 5)
end_time = time.time()
print("Time 100x100, 5 threads (processes): ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_100", 8)
end_time = time.time()
print("Time 100x100, 8 threads (processes): ", end_time - start_time)
# ----------------------------------------------------------------------------------------------------
print("\n" + "-" * 50 + "\n")
start_time = time.time()
matrix_multiplication(matrix_first, matrix_second, "matrix_300")
end_time = time.time()
print("Time 300x300: ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_300", 3)
end_time = time.time()
print("Time 300x300, 3 threads (processes): ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_300", 5)
end_time = time.time()
print("Time 300x300, 5 threads (processes): ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_300", 8)
end_time = time.time()
print("Time 300x300, 8 threads (processes): ", end_time - start_time)
# ----------------------------------------------------------------------------------------------------
print("\n" + "-" * 50 + "\n")
start_time = time.time()
matrix_multiplication(matrix_first, matrix_second, "matrix_500")
end_time = time.time()
print("Time 500x500: ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_500", 3)
end_time = time.time()
print("Time 500x500, 3 threads (processes): ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_500", 5)
end_time = time.time()
print("Time 500x500, 5 threads (processes): ", end_time - start_time)
start_time = time.time()
matrix_multiplication_treads(matrix_first, matrix_second, "matrix_500", 8)
end_time = time.time()
print("Time 500x500, 8 threads (processes): ", end_time - start_time)
run_program()