Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions Alexander_Garin/Alexander_Garin_report.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
\documentclass[a4paper]{article}

\usepackage[a4paper, top=8mm, bottom=8mm, left=8mm, right=8mm]{geometry}

\usepackage{polyglossia}
\setdefaultlanguage[babelshorthands=true]{russian}
\setotherlanguage{english}

\usepackage{fontspec}
\setmainfont{FreeSerif}
\newfontfamily{\russianfonttt}[Scale=0.7]{DejaVuSansMono}

\usepackage[tiny, compact]{titlesec}

\usepackage{titling}
\setlength{\droptitle}{-1cm}
\pretitle{\begin{center}\begin{bfseries}\Large}
\posttitle{\par\end{bfseries}\end{center}}
\preauthor{\begin{center}\normalsize}
\postauthor{\par\end{center}\vspace{-1.8cm}}

\usepackage{hyperref}
\usepackage{bookmark}
\usepackage{csquotes}
\usepackage{amsmath}

\title{Исследование способов оптимизации операции перемножения плотных матриц (SGEMM) на архитектуре AMD RDNA3 с использованием OpenCL}

\author{Гарин Александр Евгеньевич}

\date{}

\begin{document}

\maketitle

\begin{flushright}
Группа: 25.Б71-мм \\
Кафедра: системного программирования \\
Научный руководитель: Григорьев Семен Вячеславович \\
Номер семестра практики: 2
\end{flushright}


\section{Постановка задачи}

Операция перемножения плотных матриц одинарной точности (SGEMM) является классической задачей для изучения и тестирования методов низкоуровневой оптимизации вычислений на графических процессорах (Graphics Processing Unit, GPU). Эффективная реализация этой операции требует глубокого понимания работы подсистемы памяти и распределения потоков, что делает её отличным полигоном для исследования.

\textbf{Целью работы является} исследование и последовательная оптимизация вычислительных ядер SGEMM для интегрированного GPU AMD Radeon 760M (архитектура RDNA3) с использованием фреймворка OpenCL.

Большинство существующих алгоритмов и учебных материалов по данной теме жестко ориентированы на архитектуру дискретных видеокарт NVIDIA. В связи с этим практический интерес представляет исследование того, как стандартные методы оптимизации ведут себя на интегрированной графике (Accelerated Processing Unit, APU) от компании AMD. Результаты работы позволяют на конкретном примере оценить, насколько классические подходы применимы к оборудованию с другой логикой работы памяти, и выявить специфические архитектурные ограничения платформы RDNA3.

\section{Описание предлагаемого решения}

Реализована пошаговая цепочка оптимизаций OpenCL-ядер для операции SGEMM, охватывающая ключевые архитектурные техники низкоуровневого программирования. Проект основан на открытом руководстве Седрика Нугтерена\footnote{C.~Nugteren. OpenCL SGEMM tutorial. URL: \url{https://cnugteren.github.io/tutorial/pages/page1.html} (дата обращения: 07.07.2026).} и адаптирован с учётом специфики аппаратных блоков вычислений AMD.

Реализация осуществлялась в операционной системе Ubuntu 24.04 LTS с использованием следующего стека технологий: C++11 (компилятор GCC/g++, флаги \texttt{-O3 -Wall}), OpenCL 3.0 и базовая среда выполнения AMD ROCm (Radeon Open Compute).

Последовательность разработанных ядер включает:
\begin{itemize}
\item \textbf{Ядро 1 (Naive)}~- базовая реализация с прямым обращением к глобальной памяти.
\item \textbf{Ядро 2 (LDS Tiling)}~- разбиение исходных матриц на подматрицы (блоки, или тайлы) и их предварительная загрузка в локальную разделяемую память (Local Data Share, LDS). Это позволяет существенно сократить избыточный трафик к медленной глобальной памяти устройства.
\item \textbf{Ядро 3 (1D WPT)}~- увеличение объёма работы на поток (Work-Per-Thread) вдоль одного измерения.
\item \textbf{Ядро 4 (Vector)}~- явная векторизация вычислений через тип \texttt{float4} для объединения транзакций памяти.
\item \textbf{Ядро 5 (Padding)}~- введение искусственного сдвига адресов (отступа) в LDS-буфере для устранения конфликтов банков памяти.
\item \textbf{Ядро 6 (2D Block)}~- двумерное блокирование регистрового аккумулятора внутри одного потока.
\item \textbf{Ядро 7 (Caching)}~- временное кэширование строк матрицы в регистрах внешнего цикла.
\item \textbf{Ядро 10 (Universal)}~- обобщённое ядро с граничными проверками для корректной обработки матриц произвольных размеров.
\end{itemize}

Из 11 вычислительных ядер оригинального руководства в итоговую работу вошли 8. Ряд ядер (включая Ядро 8 с агрессивной предвыборкой данных) имеют жесткую аппаратную привязку к архитектурам дискретных GPU NVIDIA. Попытка их запуска на интегрированной графике AMD Radeon 760M приводила к аппаратному зависанию (dead freeze) всей системы на уровне видеодрайвера, требующему перезагрузки ноутбука. Данный сбой задокументирован как результат, подтверждающий глубокие различия в логике подсистем памяти разных производителей GPU.

Для автоматизации поиска оптимальных параметров ядра 4 был разработан bash-скрипт \texttt{extra/tuner.sh}, осуществляющий динамический перебор пространства конфигураций без ручной модификации исходного кода.

\section{Эксперименты}

Конфигурация стенда: ноутбук Honor MagicBook X 16 (BORN-H5651), процессор AMD Ryzen 5 7640HS, интегрированный графический чип AMD Radeon 760M (архитектура RDNA3, кодовое имя \texttt{gfx1103}). Операционная система: Ubuntu 24.04 LTS.

Методология: тестирование базовых ядер проводилось на квадратных плотных матрицах размера $4096 \times 4096$. Данный размер (степень двойки) является стандартным для профилирования, так как он достаточно велик для полной загрузки вычислительных блоков GPU и скрытия задержек памяти, но при этом гарантированно помещается в доступной оперативной памяти интегрированной системы (около 192~МБ для трех матриц). Каждое ядро запускалось 10~раз подряд для минимизации влияния системного планировщика. По результатам измерений фиксировались среднее время выполнения алгоритма в секундах, производительность вычислений (GFLOPS) и математический разброс (в виде стандартного отклонения от среднего значения производительности).

Пересчет времени выполнения в метрику производительности производился по стандартной формуле:
$$ \text{GFLOPS} = \frac{2 \cdot M \cdot N \cdot K}{t \cdot 10^9} $$
где $t$~- среднее время работы ядра в секундах, а $2 \cdot M \cdot N \cdot K$~- общее число операций над плавающей точкой (каждый элемент результирующей матрицы требует $K$ умножений и $K$ сложений).

\vspace{0.3cm}
\textbf{Результаты базовой оптимизации вычислений:}
\vspace{0.2cm}

\begin{center}
\begin{tabular}{|l|c|c|c|l|}
\hline
\textbf{Ядро} & \textbf{Время, с} & \textbf{GFLOPS} & \textbf{Разброс} & \textbf{Применяемая техника} \\
\hline
1 - Naive & $\approx 3.626$ & 37.9 & $\pm 0.2$ & Базовая реализация \\
2 - LDS Tiling & $\approx 0.521$ & 263.4 & $\pm 14.5$ & Разделяемая память (блоки) \\
3 - 1D WPT & $\approx 0.303$ & 452.7 & $\pm 29.4$ & Увеличение работы на поток \\
4 - Vector & $\approx 0.297$ & 461.2 & $\pm 30.1$ & Векторизация (\texttt{float4}) \\
5 - Padding & $\approx 0.460$ & 298.4 & $\pm 15.1$ & Отступ LDS (\textbf{регрессия}) \\
6 - 2D Block & $\approx 0.323$ & 425.4 & $\pm 36.2$ & 2D-блокирование регистров \\
7 - Caching & $\approx 0.310$ & 443.2 & $\pm 38.0$ & Кэширование в регистрах \\
10 - Universal & $\approx 0.424$ & 316.0 & $\pm 15.0$ & Граничные проверки \\
\hline
\end{tabular}
\end{center}

Переход к тайловой организации и векторизации (Ядро 4) позволил поднять производительность алгоритма в 12.2~раза относительно наивного варианта.

\textbf{Анализ архитектурных особенностей AMD RDNA3:}
\begin{itemize}
\item \textbf{Регрессия Padding (Ядро 5):} Метод искусственного сдвига адресов памяти, ускоряющий вычисления на NVIDIA, на архитектуре AMD RDNA3 вызвал падение скорости на 35~\%. Изменение шага обращения нарушило порядок расположения данных. Вместо того чтобы эффективно загружать память большими сплошными блоками, GPU начал считывать данные "вразнобой", что привело к лишним операциям чтения и падению скорости.
\item \textbf{Нехватка регистров (Ядро 6):} Выделение большого двумерного массива внутри потока потребовало слишком много физической памяти видеокарты. Из-за этого драйверу пришлось запускать меньше потоков одновременно, что снизило общую скорость.
\end{itemize}

\textbf{Результаты автоматического подбора параметров (Auto-Tuning):}
Скрипт перебирал размеры тайлов (Tile Size, TS) $TS \in \{16, 32\}$ и объем работы на поток $WPT \in \{4, 8\}$ для векторизованного ядра.

\begin{center}
\begin{tabular}{|c|c|c|c|l|}
\hline
\textbf{TS} & \textbf{WPT} & \textbf{GFLOPS} & \textbf{Разброс} & \textbf{Статус конфигурации} \\
\hline
16 & 4 & 462.7 & $\pm 50.8$ & Базовая стабильная конфигурация \\
16 & 8 & 474.0 & $\pm 31.2$ & Эффективное использование кэша \\
\textbf{32} & \textbf{4} & \textbf{477.0} & $\pm \textbf{45.1}$ & \textbf{Аппаратный оптимум (Sweet Spot)} \\
32 & 8 & 433.9 & $\pm 37.2$ & Переполнение регистрового файла \\
\hline
\end{tabular}
\end{center}

Конфигурация $TS=32$, $WPT=4$ обеспечивает максимальную производительность вычислений в 477.0 GFLOPS. Дальнейшее увеличение WPT до 8 приводит к тому, что быстрых регистров перестает хватать. Видеокарта начинает использовать медленную память, из-за чего скорость резко падает.

\section{Заключение}

В ходе выполнения работы получены следующие результаты:
\begin{itemize}
\item Реализована и протестирована вычислительная серия из 8 OpenCL-ядер для перемножения плотных матриц. Достигнуто ускорение вычислений в 12.2~раза (до 461.2 GFLOPS).
\item Экспериментально доказана неэффективность применения метода Padding на архитектуре AMD RDNA3 (падение производительности ядер на 35~\%).
\item Задокументирован и проанализирован критический отказ видеодрайвера (dead freeze) при попытке портирования узкоспециализированных оптимизаций под дискретные карты NVIDIA.
\item Разработан скрипт автоматического поиска параметров, выявивший оптимальную конфигурацию вычислительной нагрузки ($TS=32$, $WPT=4$), позволившую достичь пика в 477.0 GFLOPS.
\end{itemize}

Репозиторий с исходным кодом, скриптами автоматизации и результатами измерений размещён по адресу: \url{https://github.com/aleksandrgarin/myGEMM/tree/practice-optimization}

\end{document}
4 changes: 4 additions & 0 deletions main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@
\includepdf[pages=-,
addtotoc={1, section, 1, {Горбузова Мария Романовна, Реализация свёртки изображений}, gorbuzova_maria}]
{Maria_Gorbuzova/Maria_Gorbuzova_report.pdf}
\includepdf[pages=-,
addtotoc={1, section, 1, {Гарин Александр Евгеньевич, Практика OpenCL}, garin_alexander}]
{Alexander_Garin/Alexander_Garin_report.pdf}

\end{document}