DAS_2024_1/minhasapov_ruslan_lab_5
2024-11-18 02:27:55 +04:00
..
MatrixMultiplication minhasapov_ruslan_lab_5 2024-11-18 02:27:55 +04:00
.gitignore minhasapov_ruslan_lab_5 2024-11-18 02:27:55 +04:00
README.md minhasapov_ruslan_lab_5 2024-11-18 02:27:55 +04:00

Лабораторная работа №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), но может варьироваться в зависимости от размера матрицы и других факторов. Результаты подчеркивают важность баланса между распараллеливанием вычислений и накладными расходами на управление потоками.


Демонстрация

Видео доступно по ссылке