tukaeva_alfiya_lab_5 #103
@ -1 +1 @@
|
|||||||
Consumer_1.py
|
main.py
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
4
.idea/misc.xml
Normal file
4
.idea/misc.xml
Normal 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.9 (tukaeva_alfiya_lab_4)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
30
tukaeva_alfiya_lab_5/README.md
Normal file
30
tukaeva_alfiya_lab_5/README.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Лабораторная работа №5 - Параллельное умножение матриц
|
||||||
|
|
||||||
|
## Задание
|
||||||
|
|
||||||
|
|
||||||
|
* Кратко: реализовать умножение двух больших квадратных матриц.
|
||||||
|
|
||||||
|
* Подробно: в лабораторной работе требуется сделать два алгоритма: обычный и параллельный (задание со * - реализовать это в рамках одного алгоритма). В параллельном алгоритме предусмотреть ручное задание количества потоков (число потоков = 1 как раз и реализует задание со *), каждый из которых будет выполнять умножение элементов матрицы в рамках своей зоны ответственности.
|
||||||
|
|
||||||
|
## Работа программы:
|
||||||
|
|
||||||
|
1. Генерируются случайные матрицы A и B заданных размеров.
|
||||||
|
|
||||||
|
2. multiply_matrices_sequential(A, B) умножает две матрицы A и B последовательно, используя вложенные циклы для вычисления элементов результирующей матрицы C.
|
||||||
|
|
||||||
|
3. multiply_matrices_parallel(A, B, num_workers) выполняет параллельное умножение матриц с использованием пула процессов.
|
||||||
|
|
||||||
|
4. benchmark(matrix_size, num_workers) Измеряет время выполнения операций умножения. И выводит результат в консоль.
|
||||||
|
|
||||||
|
### Результат:
|
||||||
|
|
||||||
|
![](result.png "")
|
||||||
|
|
||||||
|
### Вывод:
|
||||||
|
|
||||||
|
Параллельный подход может быть более быстрым, чем последовательный на матрицах большого размера, так как он позволяет производить более эффективное распределение работы между процессами. Однако на маленьких матрицах небольшая задержка на создание и инициализацию нескольких процессов может оказаться более затратным, чем просто выполнение умножения последовательно.
|
||||||
|
|
||||||
|
|
||||||
|
# Видео
|
||||||
|
https://vk.com/video230744264_456239107?list=ln-S0qfmD3VN0JZC8Nh6o
|
61
tukaeva_alfiya_lab_5/project/main.py
Normal file
61
tukaeva_alfiya_lab_5/project/main.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import numpy as np
|
||||||
|
import time
|
||||||
|
from multiprocessing import Pool
|
||||||
|
|
||||||
|
def multiply_matrices_sequential(A, B):
|
||||||
|
"""Последовательное умножение матриц."""
|
||||||
|
n = A.shape[0]
|
||||||
|
C = np.zeros((n, n))
|
||||||
|
for i in range(n):
|
||||||
|
for j in range(n):
|
||||||
|
C[i][j] = np.dot(A[i], B[:, j]) # Используем векторизированное умножение для повышения производительности
|
||||||
|
return C
|
||||||
|
|
||||||
|
def worker(args):
|
||||||
|
"""Функция для параллельного умножения матриц, которая обрабатывает строки."""
|
||||||
|
A, B, row_indices = args
|
||||||
|
C_part = np.zeros((len(row_indices), B.shape[1]))
|
||||||
|
|
||||||
|
for idx, i in enumerate(row_indices):
|
||||||
|
C_part[idx] = np.dot(A[i], B)
|
||||||
|
|
||||||
|
return C_part
|
||||||
|
|
||||||
|
def multiply_matrices_parallel(A, B, num_workers):
|
||||||
|
"""Параллельное умножение матриц."""
|
||||||
|
n = A.shape[0]
|
||||||
|
C = np.zeros((n, n))
|
||||||
|
row_indices = np.array_split(range(n), num_workers)
|
||||||
|
|
||||||
|
with Pool(processes=num_workers) as pool:
|
||||||
|
results = pool.map(worker, [(A, B, idx) for idx in row_indices])
|
||||||
|
|
||||||
|
# Объединяем результаты
|
||||||
|
for i, result in enumerate(results):
|
||||||
|
C[i * len(result): (i + 1) * len(result)] = result
|
||||||
|
|
||||||
|
return C
|
||||||
|
|
||||||
|
def benchmark(matrix_size, num_workers):
|
||||||
|
# Генерация случайных матриц
|
||||||
|
A = np.random.rand(matrix_size, matrix_size)
|
||||||
|
B = np.random.rand(matrix_size, matrix_size)
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
if num_workers == 1:
|
||||||
|
C = multiply_matrices_sequential(A, B)
|
||||||
|
else:
|
||||||
|
C = multiply_matrices_parallel(A, B, num_workers)
|
||||||
|
end_time = time.time()
|
||||||
|
|
||||||
|
method = "последовательное" if num_workers == 1 else f"параллельное с {num_workers} потоками"
|
||||||
|
print(f"{method.capitalize()} умножение матриц {matrix_size}x{matrix_size}: {end_time - start_time:.6f} сек")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Запуск бенчмарков
|
||||||
|
sizes = [100, 300, 500]
|
||||||
|
for size in sizes:
|
||||||
|
print(f"\nБенчмарк для матриц размером {size}x{size}:")
|
||||||
|
benchmark(size, 1) # Последовательный
|
||||||
|
benchmark(size, 4) # Параллельный (4 потока)
|
||||||
|
benchmark(size, 8) # Параллельный (8 потоков)
|
BIN
tukaeva_alfiya_lab_5/result.png
Normal file
BIN
tukaeva_alfiya_lab_5/result.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
Loading…
Reference in New Issue
Block a user