Merge pull request 'turner_ilya_lab_5' (#156) from turner_ilya_lab_5 into main

Reviewed-on: #156
This commit is contained in:
Alexey 2024-11-28 23:09:51 +04:00
commit c22cca92ad
3 changed files with 76 additions and 0 deletions

View File

@ -0,0 +1,18 @@
# Лабораторная работа №5 - Параллельное перемножение матриц
## ПИбд-42 || Тюрнер Илья
### Цель лабораторной работы
Изучение принципов работы праллельных вычислений, когда они оправданы, а когда нет.
### Описание:
Был реализован механизм параллельного перемножения матриц 100x100, 300x300 и 500x500 с возможностью задания потоков, в том числе и 1 (последовательное перемножение). Были сделаны замеры времени для каждого вычисления, проведен анализ и сделаны выводы.
### Результаты:
![Изображение 1](./results.png)
### Выводы:
При параллельном перемножении матриц мы стремимся снизить временные затраты за счет увеличения числа потоков, на крупных матрицах это действительно дает ощутимый эффект. Однако, такое выполнение оправдано только тогда, когда затраты организацию многопоточности не превышают выигрыш от такой работы, т. е. для мелких задач такой подход не стоит применять, что можно заметить по перемножению матриц 100x100, там выигрыша практически нет. Также в определенный момент увеличение числа потоков в принципе перестает давать выигрыш. В таком случае оптимальное количество потоков было определено.
### Видео с демонстрацией работы:
Размещено на платформе VK видео
https://vk.com/video/@tyurner02?z=video303312410_456239081%2Fpl_303312410_-2

58
turner_ilya_lab_5/main.py Normal file
View File

@ -0,0 +1,58 @@
import random
import time
import multiprocessing
import numpy as np
# Генерация матрицы
def generate_matrix(size):
return [[random.randint(0, 10) for _ in range(size)] for _ in range(size)]
# Умножение одной строки
def multiply_row(i, A, B, result):
size = len(A)
for j in range(size):
for k in range(size):
result[i][j] += A[i][k] * B[k][j]
# параллельное умножение матриц с помощью multiprocessing
def parallel_matrix_multiply(A, B, num_processes):
size = len(A)
result = [[0] * size for _ in range(size)]
with multiprocessing.Pool(processes=num_processes) as pool:
pool.starmap(multiply_row, [(i, A, B, result) for i in range(size)])
return result
# Замер времени на умножение
def benchmark(size, num_processes=1):
A = generate_matrix(size)
B = generate_matrix(size)
start_time = time.time()
parallel_matrix_multiply(A, B, num_processes)
par_time = time.time() - start_time
return par_time
def main():
# Размеры матриц
matrix_sizes = [100, 300, 500]
# Количество потоков
num_processes_list = [1, 2, 4, 6, 8]
# Таблица с бенчмарками
print("-*" * 40)
print(f"{'Количество потоков':<20}{'|100x100 (сек.)':<20}{'|300x300 (сек.)':<20}{'|500x500 (сек.)'}")
print("-*" * 40)
for num_processes in num_processes_list:
row = f"{num_processes:<20}"
for size in matrix_sizes:
par_time = benchmark(size, num_processes)
row += f"|{par_time:.4f}".ljust(20)
print(row)
print("-*" * 40)
if __name__ == "__main__":
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB