Merge pull request 'agliullov daniyar lab 5 is ready' (#181) from agliullov_daniyar_lab_5 into main
Reviewed-on: #181
This commit is contained in:
commit
6d19011cf8
BIN
agliullov_daniyar_lab_5/Screenshots/1.png
Normal file
BIN
agliullov_daniyar_lab_5/Screenshots/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
Binary file not shown.
After Width: | Height: | Size: 187 KiB |
68
agliullov_daniyar_lab_5/main.py
Normal file
68
agliullov_daniyar_lab_5/main.py
Normal file
@ -0,0 +1,68 @@
|
||||
import multiprocessing
|
||||
import random
|
||||
import time
|
||||
from pprint import pprint
|
||||
from multiprocessing import Pool
|
||||
|
||||
|
||||
def create_random_matrix(size):
|
||||
return [[random.random() for _ in range(size)] for __ in range(size)]
|
||||
|
||||
# def matrix_multiply_seq(matrix1: list[list[float]], matrix2: list[list[float]]) -> list[list[float]]:
|
||||
# """Выполняет последовательное перемножение двух матриц и возвращает результирующую матрицу"""
|
||||
# l1 = len(matrix1)
|
||||
# l2 = len(matrix2)
|
||||
# result = [[0 for _ in range(l2)] for __ in range(l1)]
|
||||
# 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
|
||||
|
||||
|
||||
matrix_result = [[0 for _ in range(1000)] for __ in range(1000)]
|
||||
|
||||
def matrix_multiply(args) -> None:
|
||||
"""Перемножает строки от start_cnt до end_cnt, результат помещает в глобальную переменную matrix_result"""
|
||||
matrix1, matrix2, start_cnt, end_cnt = args
|
||||
for i in range(start_cnt, end_cnt):
|
||||
for j in range(len(matrix2)):
|
||||
for k in range(len(matrix2)):
|
||||
matrix_result[i][j] += matrix1[i - start_cnt][k] * matrix2[k][j]
|
||||
|
||||
|
||||
def matrix_multiply_parralel(matrix1: list[list[float]], matrix2: list[list[float]], thread_count):
|
||||
"""Выполняет парралеьное перемножение матриц"""
|
||||
l1 = len(matrix1)
|
||||
|
||||
step = l1 // thread_count
|
||||
args = [(matrix1, matrix2, i, i + step) for i in range(0, l1, step)]
|
||||
args[-1] = (matrix1, matrix2, step * (l1 - 1), l1) # Остаток на последний поток
|
||||
|
||||
with Pool(processes=thread_count) as pool:
|
||||
pool.map(matrix_multiply, args)
|
||||
# pprint(matrix_result, compact=True)
|
||||
|
||||
def main():
|
||||
sizes = [100, 300, 500, 1000]
|
||||
num_threads = [2, 4, 6, 8, 12, 16, 20]
|
||||
print(f"cpu_count: {multiprocessing.cpu_count()}")
|
||||
|
||||
for size in sizes:
|
||||
matrix1 = create_random_matrix(size)
|
||||
matrix2 = create_random_matrix(size)
|
||||
t0 = time.perf_counter()
|
||||
matrix_multiply((matrix1, matrix2, 0, len(matrix1)))
|
||||
# pprint(matrix_result[:size][:size], compact=True)
|
||||
print(f"Время последовательного перемножения матриц {size=:4}: \t\t\t\t{time.perf_counter() - t0:.3f}s")
|
||||
|
||||
for threads in num_threads:
|
||||
start_time = time.perf_counter()
|
||||
matrix_multiply_parralel(matrix1, matrix2, threads)
|
||||
end_time = time.perf_counter()
|
||||
print(f"Время парралельного перемножения матриц {size=:4}, {threads=} : \t{end_time - start_time:.3f}")
|
||||
|
||||
print("-" * 100)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
17
agliullov_daniyar_lab_5/readme.md
Normal file
17
agliullov_daniyar_lab_5/readme.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Аглиуллов Данияр ИСЭбд-41
|
||||
# Лабораторная работа №5
|
||||
|
||||
В ходе выполнения задачи по умножению квадратных матриц с использованием обычного и параллельного алгоритмов были получены следующие результаты и выводы:
|
||||
|
||||
Результаты тестов:
|
||||
![изображение 1](./Screenshots/1.png)
|
||||
![изображение 2](./Screenshots/Снимок%20экрана%202024-11-13%20160640.png)
|
||||
|
||||
Сравнение производительности:
|
||||
|
||||
• В тестах на матрицах размером 100x100, 300x300 и 500x500 было замечено, что параллельный алгоритм демонстрирует значительное сокращение времени выполнения по сравнению с обычным алгоритмом, особенно на больших матрицах. Это подтверждает эффективность использования многопоточности для задач, требующих больших вычислительных ресурсов.
|
||||
|
||||
• На малых размерах матриц (например, 100x100) преимущество было за последовательным умножением матрицы из-за накладных расходов на создание пула потоков. Однако при увеличении размера матриц (300x300 и 500x500) преимущества параллельного подхода становились более очевидными.
|
||||
• При превышении количества физических потоков процессора, производительность понижается за счет смены контекста при переключении виртуальных потоков на одном ядре
|
||||
|
||||
![Видео](https://disk.yandex.ru/d/RK_c82BrLw2KjQ)
|
Loading…
Reference in New Issue
Block a user