kurushina_ksenia_lab_5 #333
64
kurushina_ksenia_lab_5/README.md
Normal file
64
kurushina_ksenia_lab_5/README.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Лабораторная работа: Реализация умножения матриц
|
||||
|
||||
## Краткое описание
|
||||
|
||||
**Цель работы** – разработать и сравнить последовательный и
|
||||
параллельный алгоритмы умножения матриц, оценив их
|
||||
производительность на матрицах больших размеров.
|
||||
|
||||
### Основные задачи:
|
||||
1. Реализовать алгоритм последовательного умножения матриц.
|
||||
2. Создать параллельный алгоритм с настраиваемым числом потоков.
|
||||
3. Провести бенчмарки обоих алгоритмов на матрицах размером 100x100, 300x300 и 500x500.
|
||||
4. Проанализировать результаты и определить влияние размера матрицы и количества потоков на производительность.
|
||||
|
||||
## Теоретическая часть
|
||||
|
||||
Умножение матриц является ключевой операцией во многих областях, включая машинное обучение,
|
||||
обработку изображений и моделирование физических процессов. Сложность умножения двух матриц размером
|
||||
`N x N` составляет O(N³), что делает задачу вычислительно затратной. Для ускорения вычислений используется параллелизм,
|
||||
позволяющий распределить работу между несколькими потоками.
|
||||
|
||||
## Описание реализации
|
||||
|
||||
1. **Последовательный алгоритм** реализован в файле `sequential.py`. Каждый элемент результирующей матрицы вычисляется
|
||||
2. как сумма произведений соответствующих элементов
|
||||
3. строки первой матрицы и столбца второй.
|
||||
|
||||
2. **Параллельный алгоритм** описан в модуле `parallel.py`.
|
||||
3. Для выполнения вычислений используется многопоточность: каждый поток обрабатывает отдельный блок
|
||||
4. строк результирующей матрицы. Пользователь может задать число потоков для регулирования нагрузки и эффективности работы.
|
||||
|
||||
## Результаты экспериментов
|
||||
|
||||
Тесты проводились на матрицах следующих размеров: 100x100, 300x300 и 500x500.
|
||||
Для параллельного алгоритма изменялось
|
||||
число потоков, чтобы оценить их влияние на скорость вычислений.
|
||||
|
||||
|
||||
## Анализ результатов
|
||||
|
||||
1. **Эффективность параллелизма**: Параллельный алгоритм показал прирост производительности
|
||||
для больших матриц. При размере 500x500 с 4 потоками наблюдалось значительное ускорение.
|
||||
|
||||
2. **Число потоков**: Увеличение потоков улучшает производительность только до определённого момента.
|
||||
Для маленьких матриц (например, 100x100) дополнительная параллелизация может быть неэффективной.
|
||||
|
||||
3. **Ограничения параллелизма**: Накладные расходы на управление потоками
|
||||
и их синхронизацию уменьшают преимущества многопоточности при малых объёмах данных.
|
||||
|
||||
4. **Рекомендации**:
|
||||
|
||||
Параллельные алгоритмы наиболее эффективны при работе с большими матрицами.
|
||||
Настройка числа потоков должна учитывать ресурсы системы и размер задачи.
|
||||
|
||||
## Заключение
|
||||
|
||||
Данная работа продемонстрировала эффективность параллельного умножения матриц на больших данных.
|
||||
Оптимизация параметров параллельного алгоритма позволяет
|
||||
значительно сократить время выполнения задач, связанных с вычислительной обработкой матриц.
|
||||
|
||||
## Ссылка на видео
|
||||
|
||||
https://cloud.mail.ru/public/tKoW/ZLDNyHam2
|
||||
|
BIN
kurushina_ksenia_lab_5/img.png
Normal file
BIN
kurushina_ksenia_lab_5/img.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
29
kurushina_ksenia_lab_5/main.py
Normal file
29
kurushina_ksenia_lab_5/main.py
Normal file
@ -0,0 +1,29 @@
|
||||
import time
|
||||
import random
|
||||
|
||||
from DAS_2024_1.kurushina_ksenia_lab_5.parallel import matrix_multiply_parallel
|
||||
from DAS_2024_1.kurushina_ksenia_lab_5.sequential import matrix_multiply_sequential
|
||||
|
||||
|
||||
def generate_matrix(size):
|
||||
return [[random.randint(0, 10) for _ in range(size)] for _ in range(size)]
|
||||
|
||||
def benchmark(matrix_size, num_threads):
|
||||
A = generate_matrix(matrix_size)
|
||||
B = generate_matrix(matrix_size)
|
||||
|
||||
start = time.time()
|
||||
matrix_multiply_sequential(A, B)
|
||||
sequential_time = time.time() - start
|
||||
|
||||
start = time.time()
|
||||
matrix_multiply_parallel(A, B, num_threads)
|
||||
parallel_time = time.time() - start
|
||||
|
||||
print(f"Размер матрицы: {matrix_size}x{matrix_size}")
|
||||
print(f"Последовательное время: {sequential_time:.5f} сек")
|
||||
print(f"Параллельное время ({num_threads} потоков): {parallel_time:.5f} сек")
|
||||
|
||||
if __name__ == "__main__":
|
||||
for size in [100, 300, 500]:
|
||||
benchmark(size, num_threads=4)
|
21
kurushina_ksenia_lab_5/parallel.py
Normal file
21
kurushina_ksenia_lab_5/parallel.py
Normal file
@ -0,0 +1,21 @@
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
def matrix_multiply_parallel(A, B, num_threads=1):
|
||||
n = len(A)
|
||||
result = [[0] * n for _ in range(n)]
|
||||
|
||||
def worker(start, end):
|
||||
for i in range(start, end):
|
||||
for j in range(n):
|
||||
result[i][j] = sum(A[i][k] * B[k][j] for k in range(n))
|
||||
|
||||
chunk_size = n // num_threads
|
||||
with ThreadPoolExecutor(max_workers=num_threads) as executor:
|
||||
futures = [
|
||||
executor.submit(worker, i * chunk_size, (i + 1) * chunk_size)
|
||||
for i in range(num_threads)
|
||||
]
|
||||
for future in futures:
|
||||
future.result()
|
||||
|
||||
return result
|
9
kurushina_ksenia_lab_5/sequential.py
Normal file
9
kurushina_ksenia_lab_5/sequential.py
Normal file
@ -0,0 +1,9 @@
|
||||
def matrix_multiply_sequential(A, B):
|
||||
n = len(A)
|
||||
result = [[0] * n for _ in range(n)]
|
||||
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
result[i][j] = sum(A[i][k] * B[k][j] for k in range(n))
|
||||
|
||||
return result
|
Loading…
Reference in New Issue
Block a user