Merge pull request 'savenkov_alexander_lab_5_ready' (#141) from savenkov_alexander_lab_5 into main

Reviewed-on: #141
This commit is contained in:
Alexey 2024-12-10 22:03:18 +04:00
commit 1ce11b50ab
12 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="ASK" />
<option name="description" value="" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (savenkov_alexander_lab_5) (2)" project-jdk-type="Python SDK" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/savenkov_alexander_lab_5.iml" filepath="$PROJECT_DIR$/.idea/savenkov_alexander_lab_5.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,32 @@
# Лабораторная работа №5 - Вспоминаем математику или параллельное перемножение матриц
Задание:
Кратко: реализовать умножение двух больших квадратных матриц.
Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности.
Сделать несколько бенчмарков последовательного и параллельного алгоритма на умножение двух матриц размером 100x100, 300x300, 500x500 элементов.
<p>
<div>Код</div>
<img src="screens/img1.png" width="650" title="Код">
</p>
<p>
<div>Код</div>
<img src="screens/img2.png" width="650" title="Код">
</p>
<p>
<div>Код</div>
<img src="screens/img3.png" width="650" title="Код">
</p>
<p>
<div>Работа программы</div>
<img src="screens/img4.png" width="650" title="Работа программы">
</p>
Вывод: Параллельный алгоритм намного бысрее и имеет место быть если либо в матрице используются огромные числа или сама матрица намного большей размерностью
# Видео
Видео с разбором лабораторной работы - https://youtu.be/XfRcCUa_QMU

View File

@ -0,0 +1,66 @@
import numpy as np
import time
from concurrent.futures import ThreadPoolExecutor
def sequential_matrix_multiply(matrix_a, matrix_b):
"""Выполняет последовательное умножение матриц."""
return np.dot(matrix_a, matrix_b)
def parallel_matrix_multiply(matrix_a, matrix_b, num_threads=1):
"""
Выполняет параллельное умножение матриц с использованием заданного количества потоков.
Каждый поток обрабатывает свою часть строк матрицы A.
"""
result = np.zeros_like(matrix_a)
rows, cols = matrix_a.shape
chunk_size = rows // num_threads
def multiply_chunk(start_row, end_row):
"""Умножение части матрицы A на матрицу B."""
nonlocal result
for i in range(start_row, end_row):
result[i] = np.dot(matrix_a[i], matrix_b)
with ThreadPoolExecutor(max_workers=num_threads) as executor:
futures = []
for i in range(0, rows, chunk_size):
end_row = min(i + chunk_size, rows)
futures.append(executor.submit(multiply_chunk, i, end_row))
for future in futures:
future.result()
return result
def benchmark(matrix_size, num_threads=1):
"""
Измеряет время выполнения последовательного и параллельного умножения матриц
заданного размера с использованием заданного количества потоков.
"""
matrix_a = np.random.randint(0, 10, size=(matrix_size, matrix_size))
matrix_b = np.random.randint(0, 10, size=(matrix_size, matrix_size))
# Замер времени для последовательного алгоритма
start_time = time.time()
sequential_result = sequential_matrix_multiply(matrix_a, matrix_b)
sequential_time = time.time() - start_time
# Замер времени для параллельного алгоритма
start_time = time.time()
parallel_result = parallel_matrix_multiply(matrix_a, matrix_b, num_threads)
parallel_time = time.time() - start_time
return sequential_time, parallel_time
if __name__ == "__main__":
matrix_sizes = [100, 300, 500]
num_threads = int(input("Введите количество потоков: "))
for size in matrix_sizes:
print(f"Matrix size: {size}x{size}")
sequential_time, parallel_time = benchmark(size, num_threads)
print(f"Sequential algorithm time: {sequential_time:.6f} seconds")
print(f"Parallel algorithm time ({num_threads} threads): {parallel_time:.6f} seconds")
print("="*30)

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB