# Лабораторная работа №5 #### ПИбд-42. Минхасапов Руслан. --- **Цель:** Реализовать последовательный и параллельный алгоритмы умножения квадратных матриц и сравнить их производительность. --- **Описание задачи:** В работе реализованы два алгоритма умножения матриц: * **Последовательный:** Классический алгоритм умножения матриц с тремя вложенными циклами. * **Параллельный:** Алгоритм, распараллеливающий вычисления по строкам результирующей матрицы. Каждому потоку назначается подмножество строк для вычисления. Число потоков задается параметром. --- **Описание параллельного алгоритма:** Параллельный алгоритм `multiplyParallel` разделяет вычисления между заданным количеством потоков. Входные матрицы `A` и `B`, а также результирующая матрица `C` передаются в каждый поток. 1. **Разделение по строкам:** Матрица `C` разделяется на блоки по строкам. Каждый поток отвечает за вычисление элементов в своем блоке строк. Количество строк на поток рассчитывается как `size / numThreads`, где `size` - размер матрицы, а `numThreads` - количество потоков. 2. **Создание потоков:** Создается массив потоков `threads`. Каждый поток выполняет функцию `multiplyPart`, которая вычисляет значения элементов в заданном диапазоне строк. 3. **Запуск и синхронизация:** Все потоки запускаются с помощью `t.Start()`. Затем основной поток ожидает завершения всех потоков с помощью `t.Join()`. Это гарантирует, что все вычисления будут завершены до возвращения результата. 4. **Возврат результата:** После завершения всех потоков функция `multiplyParallel` возвращает результирующую матрицу `C`. --- **Результаты бенчмарков:** Были проведены тесты для матриц размером 100x100, 300x300 и 500x500 элементов с разным количеством процессов (2, 4, 8, 16, 32, 64, 128, 256, 512). Результаты представлены в таблице: | Размер | Кол-во потоков | Алгоритм | Время (мс) | |---|---|---|---| | 100x100 | 1 | Последовательный | 11 | | 100x100 | 2 | Параллельный | 7 | | 100x100 | 4 | Параллельный | 6 | | 100x100 | 8 | Параллельный | 5 | | 100x100 | 16 | Параллельный | 6 | | 100x100 | 32 | Параллельный | 6 | | 100x100 | 64 | Параллельный | 14 | | 100x100 | 128 | Параллельный | 27 | | 100x100 | 256 | Параллельный | 44 | | 100x100 | 512 | Параллельный | 69 | | 300x300 | 1 | Последовательный | 393 | | 300x300 | 2 | Параллельный | 177 | | 300x300 | 4 | Параллельный | 197 | | 300x300 | 8 | Параллельный | 155 | | 300x300 | 16 | Параллельный | 148 | | 300x300 | 32 | Параллельный | 139 | | 300x300 | 64 | Параллельный | 153 | | 300x300 | 128 | Параллельный | 154 | | 300x300 | 256 | Параллельный | 167 | | 300x300 | 512 | Параллельный | 358 | | 500x500 | 1 | Последовательный | 1616 | | 500x500 | 2 | Параллельный | 831 | | 500x500 | 4 | Параллельный | 598 | | 500x500 | 8 | Параллельный | 522 | | 500x500 | 16 | Параллельный | 542 | | 500x500 | 32 | Параллельный | 578 | | 500x500 | 64 | Параллельный | 642 | | 500x500 | 128 | Параллельный | 812 | | 500x500 | 256 | Параллельный | 1038 | | 500x500 | 512 | Параллельный | 1496 | --- **Анализ результатов:** * **Влияние размера матрицы:** Время выполнения обоих алгоритмов ожидаемо растет с увеличением размера матрицы, подтверждая кубическую сложность O(n³). * **Влияние числа потоков:** Параллельный алгоритм демонстрирует ускорение по сравнению с последовательным. Наиболее заметное ускорение наблюдается при умеренном количестве потоков. Для матрицы 100x100 оптимальное количество потоков — 8, для 300x300 — 32, а для 500x500 — 8. * **Ухудшение производительности при большом числе потоков:** При слишком большом количестве потоков (64, 128, 256, 512) производительность начинает ухудшаться из-за накладных расходов на создание, управление и синхронизацию потоков. Эти расходы перевешивают выгоду от распараллеливания, особенно на относительно небольших матрицах. * **Оптимальное число потоков:** Оптимальное количество потоков нелинейно зависит от размера матрицы и, вероятно, ограничено количеством логических ядер процессора. В данном случае, для матриц большего размера оптимальное число потоков меньше максимального протестированного, что указывает на наличие узкого места, связанного с управлением потоками. **Выводы:** Параллельное умножение матриц может значительно ускорить вычисления, но требует настройки количества потоков. Слишком большое количество потоков приводит к снижению производительности. Оптимальное количество потоков близко к количеству логических ядер процессора (8), но может варьироваться в зависимости от размера матрицы и других факторов. Результаты подчеркивают важность баланса между распараллеливанием вычислений и накладными расходами на управление потоками. --- #### Демонстрация Видео доступно по [ссылке](https://disk.yandex.ru/i/aG-7_gTgRwqf5A)