From 622d6a701200c31898daf4fb721fdba475596a57 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 11 Jun 2026 15:05:53 +0300 Subject: [PATCH 01/12] Add report --- Danil_Grezin/Danil_Grezin_report.tex | 129 +++++++++++++++++++++++++++ main.tex | 3 + 2 files changed, 132 insertions(+) create mode 100644 Danil_Grezin/Danil_Grezin_report.tex diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex new file mode 100644 index 0000000..d010c52 --- /dev/null +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -0,0 +1,129 @@ +\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} + + +\title{GEMM OpenCL} + +\author{Грезин Данил Максимович} + +\date{} + +\begin{document} +\maketitle +\begin{flushright} +\begin{tabular}{r} + Группа: \emph{\enquote{25.Б41-мм}} \\ + Кафедра: \emph{системного программирования} \\ + Научный руководитель: \emph{Григорьев Семен Вячеславович} \\ + Номер семестра практики: \emph{2} \\ +\end{tabular} +\end{flushright} + +\section{Постановка задачи} + +Умножение матриц является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. + +Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. + +\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность графического процессора, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. + +Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. + +Для достижения поставленной цели были решены следующие задачи: +\begin{itemize} +\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM; +\item проанализировать влияние отдельных методов оптимизации на производительность графического процессора; +\item автоматизировать подбор параметров оптимизации; +\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте по умолчанию. +\end{itemize} + +\section{Описание предлагаемого решения} + +В качестве основы для выполнения работы был использован проект myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. + +В проекте представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность графического процессора и делает проект удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. + +В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта: + +\begin{itemize} +\item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; +\item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); +\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; +\item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. +\end{itemize} + +Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. + +\section{Экспериментальное исследование производительности} + +С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. + +Эксперименты проводились на следующей конфигурации вычислительной системы: +\begin{itemize} +\item процессор AMD Ryzen 7 7435HS (8 ядер, 16 потоков); +\item оперативная память 16 ГБ; +\item графический процессор NVIDIA GeForce RTX 4060 Laptop GPU (8 ГБ); +\item операционная система Manjaro Linux; +\item драйвер NVIDIA 590.48.01; +\item CUDA Toolkit 13.1; +\item NVCC 13.1.115; +\item OpenCL 3.0; +\item компилятор GCC 15.2.1; +\item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. +\end{itemize} + +Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой неполных плиток). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. + +Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. + +В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: + +\begin{itemize} +\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера плитки (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); +\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера плитки по измерению K (TSK с 16 до 32); +\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). +\end{itemize} + +Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. + +Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. + +\section{Заключение} + +В ходе выполнения работы получены следующие результаты: + +\begin{itemize} + \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); + \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); + \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); + \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. +\end{itemize} + +Репозиторий: \url{https://github.com/Snaffys/myGEMM} + +Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. + +Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. +\end{document} diff --git a/main.tex b/main.tex index ce49627..83bce0e 100644 --- a/main.tex +++ b/main.tex @@ -40,5 +40,8 @@ \includepdf[pages=-, addtotoc={1, section, 1, {Гаврилов Максим Юрьевич, Программирование микроконтроллеров RISC-V}, gavrilov_maxim}] {Maxim_Gavrilov/Maxim_Gavrilov_report.pdf} +\includepdf[pages=-, + addtotoc={1, section, 1, {Грезин Данил Максимович, GEMM OpenCL}, grezin_danil}] +{Danil_Grezin/Danil_Grezin_report.pdf} \end{document} \end{document} From 2b235bfa6a4ac4da388a8a0d3f5d874604b80352 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 11 Jun 2026 15:33:42 +0300 Subject: [PATCH 02/12] trigger CI From 337eac6aad61cf3c2fbd42f0ead79e1ce5b3c27b Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 12 Jun 2026 20:00:35 +0300 Subject: [PATCH 03/12] Clarify terminology, improve report wording and add gfops calculation explanation --- Danil_Grezin/Danil_Grezin_report.tex | 265 ++++++++++++++------------- 1 file changed, 136 insertions(+), 129 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index d010c52..ef6a2c8 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -1,129 +1,136 @@ -\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} - - -\title{GEMM OpenCL} - -\author{Грезин Данил Максимович} - -\date{} - -\begin{document} -\maketitle -\begin{flushright} -\begin{tabular}{r} - Группа: \emph{\enquote{25.Б41-мм}} \\ - Кафедра: \emph{системного программирования} \\ - Научный руководитель: \emph{Григорьев Семен Вячеславович} \\ - Номер семестра практики: \emph{2} \\ -\end{tabular} -\end{flushright} - -\section{Постановка задачи} - -Умножение матриц является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. - -Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. - -\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность графического процессора, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. - -Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. - -Для достижения поставленной цели были решены следующие задачи: -\begin{itemize} -\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM; -\item проанализировать влияние отдельных методов оптимизации на производительность графического процессора; -\item автоматизировать подбор параметров оптимизации; -\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте по умолчанию. -\end{itemize} - -\section{Описание предлагаемого решения} - -В качестве основы для выполнения работы был использован проект myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. - -В проекте представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность графического процессора и делает проект удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. - -В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта: - -\begin{itemize} -\item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; -\item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); -\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; -\item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. -\end{itemize} - -Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. - -\section{Экспериментальное исследование производительности} - -С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. - -Эксперименты проводились на следующей конфигурации вычислительной системы: -\begin{itemize} -\item процессор AMD Ryzen 7 7435HS (8 ядер, 16 потоков); -\item оперативная память 16 ГБ; -\item графический процессор NVIDIA GeForce RTX 4060 Laptop GPU (8 ГБ); -\item операционная система Manjaro Linux; -\item драйвер NVIDIA 590.48.01; -\item CUDA Toolkit 13.1; -\item NVCC 13.1.115; -\item OpenCL 3.0; -\item компилятор GCC 15.2.1; -\item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. -\end{itemize} - -Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой неполных плиток). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. - -Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. - -В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: - -\begin{itemize} -\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера плитки (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); -\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера плитки по измерению K (TSK с 16 до 32); -\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). -\end{itemize} - -Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. - -Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. - -\section{Заключение} - -В ходе выполнения работы получены следующие результаты: - -\begin{itemize} - \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); - \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); - \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); - \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. -\end{itemize} - -Репозиторий: \url{https://github.com/Snaffys/myGEMM} - -Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. - -Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. -\end{document} +\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} + + +\title{Оптимизация умножения плотных матриц на графических процессорах с использованием OpenCL} + +\author{Грезин Данил Максимович} + +\date{} + +\begin{document} +\maketitle +\begin{flushright} +\begin{tabular}{r} + Группа: \emph{\enquote{25.Б41-мм}} \\ + Кафедра: \emph{системного программирования} \\ + Научный руководитель: \emph{Григорьев Семен Вячеславович} \\ + Номер семестра практики: \emph{2} \\ +\end{tabular} +\end{flushright} + +\section{Постановка задачи} + +Умножение плотных матриц с элементами одинарной точности (стандартный 32-битный формат представления чисел с плавающей точкой) является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. + +Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. Реализации отличаются применяемыми методами повышения производительности, направленными на сокращение числа обращений к памяти, более эффективное использование локальной памяти и регистров, а также увеличение объема вычислений, выполняемых каждым потоком. Для ряда реализаций предусмотрены настраиваемые параметры, включая размеры вычислительных блоков, объем работы, выполняемой одним потоком, и ширину используемых векторов, значения которых могут существенно влиять на достигаемую производительность. + +\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность вычислений при их выполнении на графическом процессоре, а также автоматизация подборка параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. + +Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. + +Для достижения поставленной цели были решены следующие задачи: +\begin{itemize} +\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}; +\item проанализировать влияние отдельных методов оптимизации, используемых в реализациях умножения матриц, на производительность выполнения вычислений на графическом процессоре; +\item автоматизировать подбор параметров оптимизации; +\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте myGEMM по умолчанию. +\end{itemize} + +\section{Описание предлагаемого решения} + +В качестве основы для выполнения работы был использован проект myGEMM, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. + +В проекте myGEMM представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность вычислений на графическом процессоре и делает проект myGEMM удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. + +В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта, разрабатываемого в рамках данной работы: + +\begin{itemize} +\item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; +\item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); +\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; +\item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. +\end{itemize} + +Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. + +\section{Экспериментальное исследование производительности} + +С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. + +Эксперименты проводились на следующей конфигурации вычислительной системы: +\begin{itemize} +\item процессор AMD Ryzen 7 7435HS (8 ядер, 16 потоков); +\item оперативная память 16 ГБ; +\item графический процессор NVIDIA GeForce RTX 4060 Laptop GPU (8 ГБ); +\item операционная система Manjaro Linux; +\item драйвер NVIDIA 590.48.01; +\item CUDA Toolkit 13.1; +\item NVCC 13.1.115; +\item OpenCL 3.0; +\item компилятор GCC 15.2.1; +\item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. +\end{itemize} + +Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. + +Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Число арифметических операций при умножении плотных квадратных матриц размера \(N \times N\) составляет \(2N^3\), поскольку каждый элемент результирующей матрицы вычисляется как скалярное произведение строки и столбца длины \(N\), включающее \(N\) операций умножения и \(N\) операций сложения. Итоговая производительность вычислялась по формуле: +\[ +GFLOPS = \frac{2N^3}{t \cdot 10^9}, +\] +где \(t\) — время выполнения одного измерения в секундах. + + +Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. + +В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: + +\begin{itemize} +\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера вычислительного блока (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); +\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера вычислительного блока по измерению K (TSK с 16 до 32); +\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). +\end{itemize} + +Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. + +Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. + +\section{Заключение} + +В ходе выполнения работы получены следующие результаты: + +\begin{itemize} + \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); + \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); + \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); + \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. +\end{itemize} + +Репозиторий: \url{https://github.com/Snaffys/myGEMM} + +Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. + +Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. +\end{document} \ No newline at end of file From e27aed45ed483a6a0053762b1b2ba06d8a2c9bd3 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 12 Jun 2026 20:29:38 +0300 Subject: [PATCH 04/12] Move back to the last commit to see proper changes between next commits --- Danil_Grezin/Danil_Grezin_report.tex | 265 +++++++++++++-------------- 1 file changed, 129 insertions(+), 136 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index ef6a2c8..d010c52 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -1,136 +1,129 @@ -\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} - - -\title{Оптимизация умножения плотных матриц на графических процессорах с использованием OpenCL} - -\author{Грезин Данил Максимович} - -\date{} - -\begin{document} -\maketitle -\begin{flushright} -\begin{tabular}{r} - Группа: \emph{\enquote{25.Б41-мм}} \\ - Кафедра: \emph{системного программирования} \\ - Научный руководитель: \emph{Григорьев Семен Вячеславович} \\ - Номер семестра практики: \emph{2} \\ -\end{tabular} -\end{flushright} - -\section{Постановка задачи} - -Умножение плотных матриц с элементами одинарной точности (стандартный 32-битный формат представления чисел с плавающей точкой) является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. - -Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. Реализации отличаются применяемыми методами повышения производительности, направленными на сокращение числа обращений к памяти, более эффективное использование локальной памяти и регистров, а также увеличение объема вычислений, выполняемых каждым потоком. Для ряда реализаций предусмотрены настраиваемые параметры, включая размеры вычислительных блоков, объем работы, выполняемой одним потоком, и ширину используемых векторов, значения которых могут существенно влиять на достигаемую производительность. - -\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность вычислений при их выполнении на графическом процессоре, а также автоматизация подборка параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. - -Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. - -Для достижения поставленной цели были решены следующие задачи: -\begin{itemize} -\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}; -\item проанализировать влияние отдельных методов оптимизации, используемых в реализациях умножения матриц, на производительность выполнения вычислений на графическом процессоре; -\item автоматизировать подбор параметров оптимизации; -\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте myGEMM по умолчанию. -\end{itemize} - -\section{Описание предлагаемого решения} - -В качестве основы для выполнения работы был использован проект myGEMM, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. - -В проекте myGEMM представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность вычислений на графическом процессоре и делает проект myGEMM удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. - -В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта, разрабатываемого в рамках данной работы: - -\begin{itemize} -\item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; -\item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); -\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; -\item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. -\end{itemize} - -Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. - -\section{Экспериментальное исследование производительности} - -С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. - -Эксперименты проводились на следующей конфигурации вычислительной системы: -\begin{itemize} -\item процессор AMD Ryzen 7 7435HS (8 ядер, 16 потоков); -\item оперативная память 16 ГБ; -\item графический процессор NVIDIA GeForce RTX 4060 Laptop GPU (8 ГБ); -\item операционная система Manjaro Linux; -\item драйвер NVIDIA 590.48.01; -\item CUDA Toolkit 13.1; -\item NVCC 13.1.115; -\item OpenCL 3.0; -\item компилятор GCC 15.2.1; -\item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. -\end{itemize} - -Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. - -Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Число арифметических операций при умножении плотных квадратных матриц размера \(N \times N\) составляет \(2N^3\), поскольку каждый элемент результирующей матрицы вычисляется как скалярное произведение строки и столбца длины \(N\), включающее \(N\) операций умножения и \(N\) операций сложения. Итоговая производительность вычислялась по формуле: -\[ -GFLOPS = \frac{2N^3}{t \cdot 10^9}, -\] -где \(t\) — время выполнения одного измерения в секундах. - - -Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. - -В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: - -\begin{itemize} -\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера вычислительного блока (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); -\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера вычислительного блока по измерению K (TSK с 16 до 32); -\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). -\end{itemize} - -Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. - -Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. - -\section{Заключение} - -В ходе выполнения работы получены следующие результаты: - -\begin{itemize} - \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); - \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); - \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); - \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. -\end{itemize} - -Репозиторий: \url{https://github.com/Snaffys/myGEMM} - -Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. - -Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. -\end{document} \ No newline at end of file +\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} + + +\title{GEMM OpenCL} + +\author{Грезин Данил Максимович} + +\date{} + +\begin{document} +\maketitle +\begin{flushright} +\begin{tabular}{r} + Группа: \emph{\enquote{25.Б41-мм}} \\ + Кафедра: \emph{системного программирования} \\ + Научный руководитель: \emph{Григорьев Семен Вячеславович} \\ + Номер семестра практики: \emph{2} \\ +\end{tabular} +\end{flushright} + +\section{Постановка задачи} + +Умножение матриц является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. + +Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. + +\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность графического процессора, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. + +Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. + +Для достижения поставленной цели были решены следующие задачи: +\begin{itemize} +\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM; +\item проанализировать влияние отдельных методов оптимизации на производительность графического процессора; +\item автоматизировать подбор параметров оптимизации; +\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте по умолчанию. +\end{itemize} + +\section{Описание предлагаемого решения} + +В качестве основы для выполнения работы был использован проект myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. + +В проекте представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность графического процессора и делает проект удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. + +В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта: + +\begin{itemize} +\item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; +\item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); +\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; +\item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. +\end{itemize} + +Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. + +\section{Экспериментальное исследование производительности} + +С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. + +Эксперименты проводились на следующей конфигурации вычислительной системы: +\begin{itemize} +\item процессор AMD Ryzen 7 7435HS (8 ядер, 16 потоков); +\item оперативная память 16 ГБ; +\item графический процессор NVIDIA GeForce RTX 4060 Laptop GPU (8 ГБ); +\item операционная система Manjaro Linux; +\item драйвер NVIDIA 590.48.01; +\item CUDA Toolkit 13.1; +\item NVCC 13.1.115; +\item OpenCL 3.0; +\item компилятор GCC 15.2.1; +\item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. +\end{itemize} + +Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой неполных плиток). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. + +Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. + +В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: + +\begin{itemize} +\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера плитки (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); +\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера плитки по измерению K (TSK с 16 до 32); +\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). +\end{itemize} + +Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. + +Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. + +\section{Заключение} + +В ходе выполнения работы получены следующие результаты: + +\begin{itemize} + \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); + \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); + \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); + \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. +\end{itemize} + +Репозиторий: \url{https://github.com/Snaffys/myGEMM} + +Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. + +Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. +\end{document} From e42eae107528cfddb2fd6dd8950a3f709f8ff884 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 12 Jun 2026 20:35:46 +0300 Subject: [PATCH 05/12] Normalize line endings to LF --- Danil_Grezin/Danil_Grezin_report.tex | 258 +++++++++++++-------------- 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index d010c52..932fb78 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -1,129 +1,129 @@ -\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} - - -\title{GEMM OpenCL} - -\author{Грезин Данил Максимович} - -\date{} - -\begin{document} -\maketitle -\begin{flushright} -\begin{tabular}{r} - Группа: \emph{\enquote{25.Б41-мм}} \\ - Кафедра: \emph{системного программирования} \\ - Научный руководитель: \emph{Григорьев Семен Вячеславович} \\ - Номер семестра практики: \emph{2} \\ -\end{tabular} -\end{flushright} - -\section{Постановка задачи} - -Умножение матриц является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. - -Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. - -\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность графического процессора, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. - -Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. - -Для достижения поставленной цели были решены следующие задачи: -\begin{itemize} -\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM; -\item проанализировать влияние отдельных методов оптимизации на производительность графического процессора; -\item автоматизировать подбор параметров оптимизации; -\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте по умолчанию. -\end{itemize} - -\section{Описание предлагаемого решения} - -В качестве основы для выполнения работы был использован проект myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. - -В проекте представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность графического процессора и делает проект удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. - -В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта: - -\begin{itemize} -\item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; -\item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); -\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; -\item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. -\end{itemize} - -Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. - -\section{Экспериментальное исследование производительности} - -С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. - -Эксперименты проводились на следующей конфигурации вычислительной системы: -\begin{itemize} -\item процессор AMD Ryzen 7 7435HS (8 ядер, 16 потоков); -\item оперативная память 16 ГБ; -\item графический процессор NVIDIA GeForce RTX 4060 Laptop GPU (8 ГБ); -\item операционная система Manjaro Linux; -\item драйвер NVIDIA 590.48.01; -\item CUDA Toolkit 13.1; -\item NVCC 13.1.115; -\item OpenCL 3.0; -\item компилятор GCC 15.2.1; -\item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. -\end{itemize} - -Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой неполных плиток). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. - -Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. - -В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: - -\begin{itemize} -\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера плитки (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); -\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера плитки по измерению K (TSK с 16 до 32); -\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). -\end{itemize} - -Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. - -Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. - -\section{Заключение} - -В ходе выполнения работы получены следующие результаты: - -\begin{itemize} - \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); - \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); - \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); - \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. -\end{itemize} - -Репозиторий: \url{https://github.com/Snaffys/myGEMM} - -Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. - -Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. -\end{document} +\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} + + +\title{GEMM OpenCL} + +\author{Грезин Данил Максимович} + +\date{} + +\begin{document} +\maketitle +\begin{flushright} +\begin{tabular}{r} + Группа: \emph{\enquote{25.Б41-мм}} \\ + Кафедра: \emph{системного программирования} \\ + Научный руководитель: \emph{Григорьев Семен Вячеславович} \\ + Номер семестра практики: \emph{2} \\ +\end{tabular} +\end{flushright} + +\section{Постановка задачи} + +Умножение матриц является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. + +Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. + +\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность графического процессора, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. + +Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. + +Для достижения поставленной цели были решены следующие задачи: +\begin{itemize} +\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM; +\item проанализировать влияние отдельных методов оптимизации на производительность графического процессора; +\item автоматизировать подбор параметров оптимизации; +\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте по умолчанию. +\end{itemize} + +\section{Описание предлагаемого решения} + +В качестве основы для выполнения работы был использован проект myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. + +В проекте представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность графического процессора и делает проект удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. + +В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта: + +\begin{itemize} +\item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; +\item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); +\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; +\item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. +\end{itemize} + +Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. + +\section{Экспериментальное исследование производительности} + +С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. + +Эксперименты проводились на следующей конфигурации вычислительной системы: +\begin{itemize} +\item процессор AMD Ryzen 7 7435HS (8 ядер, 16 потоков); +\item оперативная память 16 ГБ; +\item графический процессор NVIDIA GeForce RTX 4060 Laptop GPU (8 ГБ); +\item операционная система Manjaro Linux; +\item драйвер NVIDIA 590.48.01; +\item CUDA Toolkit 13.1; +\item NVCC 13.1.115; +\item OpenCL 3.0; +\item компилятор GCC 15.2.1; +\item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. +\end{itemize} + +Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой неполных плиток). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. + +Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. + +В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: + +\begin{itemize} +\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера плитки (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); +\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера плитки по измерению K (TSK с 16 до 32); +\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). +\end{itemize} + +Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. + +Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. + +\section{Заключение} + +В ходе выполнения работы получены следующие результаты: + +\begin{itemize} + \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); + \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); + \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); + \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. +\end{itemize} + +Репозиторий: \url{https://github.com/Snaffys/myGEMM} + +Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. + +Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. +\end{document} From caa155caaafbe5d393c8e283f78edf7bfe5c0fbe Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 12 Jun 2026 20:38:13 +0300 Subject: [PATCH 06/12] Clarify terminology, improve report wording and add gfops calculation explanation --- Danil_Grezin/Danil_Grezin_report.tex | 35 +++++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index 932fb78..ef6a2c8 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -24,7 +24,7 @@ \usepackage{csquotes} -\title{GEMM OpenCL} +\title{Оптимизация умножения плотных матриц на графических процессорах с использованием OpenCL} \author{Грезин Данил Максимович} @@ -43,29 +43,29 @@ \section{Постановка задачи} -Умножение матриц является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. +Умножение плотных матриц с элементами одинарной точности (стандартный 32-битный формат представления чисел с плавающей точкой) является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. -Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. +Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. Реализации отличаются применяемыми методами повышения производительности, направленными на сокращение числа обращений к памяти, более эффективное использование локальной памяти и регистров, а также увеличение объема вычислений, выполняемых каждым потоком. Для ряда реализаций предусмотрены настраиваемые параметры, включая размеры вычислительных блоков, объем работы, выполняемой одним потоком, и ширину используемых векторов, значения которых могут существенно влиять на достигаемую производительность. -\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность графического процессора, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. +\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность вычислений при их выполнении на графическом процессоре, а также автоматизация подборка параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. Для достижения поставленной цели были решены следующие задачи: \begin{itemize} -\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM; -\item проанализировать влияние отдельных методов оптимизации на производительность графического процессора; +\item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}; +\item проанализировать влияние отдельных методов оптимизации, используемых в реализациях умножения матриц, на производительность выполнения вычислений на графическом процессоре; \item автоматизировать подбор параметров оптимизации; -\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте по умолчанию. +\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте myGEMM по умолчанию. \end{itemize} \section{Описание предлагаемого решения} -В качестве основы для выполнения работы был использован проект myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. +В качестве основы для выполнения работы был использован проект myGEMM, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. -В проекте представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность графического процессора и делает проект удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. +В проекте myGEMM представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность вычислений на графическом процессоре и делает проект myGEMM удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. -В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта: +В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта, разрабатываемого в рамках данной работы: \begin{itemize} \item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; @@ -94,15 +94,22 @@ \section{Экспериментальное исследование произ \item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. \end{itemize} -Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой неполных плиток). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. +Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. + +Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Число арифметических операций при умножении плотных квадратных матриц размера \(N \times N\) составляет \(2N^3\), поскольку каждый элемент результирующей матрицы вычисляется как скалярное произведение строки и столбца длины \(N\), включающее \(N\) операций умножения и \(N\) операций сложения. Итоговая производительность вычислялась по формуле: +\[ +GFLOPS = \frac{2N^3}{t \cdot 10^9}, +\] +где \(t\) — время выполнения одного измерения в секундах. + Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: \begin{itemize} -\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера плитки (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); -\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера плитки по измерению K (TSK с 16 до 32); +\item ядро 5~--- прирост производительности около 65\% за счет увеличения размера вычислительного блока (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); +\item ядро 6~--- прирост производительности около 20\% за счет увеличения размера вычислительного блока по измерению K (TSK с 16 до 32); \item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). \end{itemize} @@ -126,4 +133,4 @@ \section{Заключение} Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. -\end{document} +\end{document} \ No newline at end of file From 3a6c877858ff30e7f5048f75bd3cc420372bdd89 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 13 Jun 2026 13:32:15 +0300 Subject: [PATCH 07/12] Change title, add graph, explain GFLOPS calculation, add period --- Danil_Grezin/Danil_Grezin_report.tex | 19 ++++++++++++++----- Danil_Grezin/kernel_comparison.pdf | Bin 0 -> 85811 bytes 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 Danil_Grezin/kernel_comparison.pdf diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index ef6a2c8..799b8b6 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -22,9 +22,10 @@ \usepackage{hyperref} \usepackage{bookmark} \usepackage{csquotes} +\usepackage{graphicx} -\title{Оптимизация умножения плотных матриц на графических процессорах с использованием OpenCL} +\title{Экспериментальное ислледование методов оптимизации умножения плотных матриц на графических процессорах с использованием OpenCL} \author{Грезин Данил Максимович} @@ -96,15 +97,23 @@ \section{Экспериментальное исследование произ Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. -Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Число арифметических операций при умножении плотных квадратных матриц размера \(N \times N\) составляет \(2N^3\), поскольку каждый элемент результирующей матрицы вычисляется как скалярное произведение строки и столбца длины \(N\), включающее \(N\) операций умножения и \(N\) операций сложения. Итоговая производительность вычислялась по формуле: +Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Хотя современные графические процессоры могут выполнять пары операций умножения и сложения с использованием инструкции FMA (Fused Multiply-Add), объединяющей обе операции в одной аппаратной инструкции, при расчете производительности такая инструкция учитывается как две операции с плавающей точкой. Итоговая производительность вычислялась по формуле: \[ GFLOPS = \frac{2N^3}{t \cdot 10^9}, \] где \(t\) — время выполнения одного измерения в секундах. - Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. +Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. + +\begin{figure}[htbp] + \centering + \includegraphics[width=0.645\textwidth]{kernel_comparison.pdf} + \caption{Производительность вычислительных ядер до и после подбора параметров} + \label{fig:kernel-comparison} +\end{figure} + В ходе эксперимента были выявлены следующие ядра, показавшие наибольший прирост производительности после оптимизации параметров: \begin{itemize} @@ -128,9 +137,9 @@ \section{Заключение} \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. \end{itemize} -Репозиторий: \url{https://github.com/Snaffys/myGEMM} +Репозиторий: \url{https://github.com/Snaffys/myGEMM}. Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. -\end{document} \ No newline at end of file +\end{document} diff --git a/Danil_Grezin/kernel_comparison.pdf b/Danil_Grezin/kernel_comparison.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1b99151f55b3925a77e4f604bb38512a0a4e7765 GIT binary patch literal 85811 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 @AP&=@qeA{e>=G=(-5Y_l4t& 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

U*85UL*BK_^eIq8J{8jv% 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 M1`-ld)l~!i53HvLI{*Lx literal 0 HcmV?d00001 From 5d06b893d2260205517aad987d4dccde5ddabaab Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 14 Jun 2026 13:35:06 +0300 Subject: [PATCH 08/12] Change dash, FMA explanation, add graph explanation --- Danil_Grezin/Danil_Grezin_report.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index 799b8b6..9b64734 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -95,21 +95,21 @@ \section{Экспериментальное исследование произ \item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. \end{itemize} -Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро--Уилка. +Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро-Уилка. -Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Хотя современные графические процессоры могут выполнять пары операций умножения и сложения с использованием инструкции FMA (Fused Multiply-Add), объединяющей обе операции в одной аппаратной инструкции, при расчете производительности такая инструкция учитывается как две операции с плавающей точкой. Итоговая производительность вычислялась по формуле: +Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Хотя современные графические процессоры могут выполнять пары операций умножения и сложения с использованием инструкции FMA (Fused Multiply-Add), объединяющей обе операции в одной аппаратной инструкции, при расчете производительности такая инструкция учитывается как две арифмитические операции с плавающей точкой, а не одна аппаратная инструкция. Итоговая производительность вычислялась по формуле: \[ GFLOPS = \frac{2N^3}{t \cdot 10^9}, \] -где \(t\) — время выполнения одного измерения в секундах. +где \(t\)~--- время выполнения одного измерения в секундах. Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. -Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. +Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Обозначение <> означает, что параметры ядра по умолчанию уже являлись оптимальными. \begin{figure}[htbp] \centering - \includegraphics[width=0.645\textwidth]{kernel_comparison.pdf} + \includegraphics[width=0.577\textwidth]{kernel_comparison.pdf} \caption{Производительность вычислительных ядер до и после подбора параметров} \label{fig:kernel-comparison} \end{figure} From 85352e9a76076ef2fd52f1969d47c6a02f8052ce Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 15 Jun 2026 11:52:13 +0300 Subject: [PATCH 09/12] Remove FMA, add graph explanation --- Danil_Grezin/Danil_Grezin_report.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index 9b64734..d49f658 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -97,7 +97,7 @@ \section{Экспериментальное исследование произ Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро-Уилка. -Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Хотя современные графические процессоры могут выполнять пары операций умножения и сложения с использованием инструкции FMA (Fused Multiply-Add), объединяющей обе операции в одной аппаратной инструкции, при расчете производительности такая инструкция учитывается как две арифмитические операции с плавающей точкой, а не одна аппаратная инструкция. Итоговая производительность вычислялась по формуле: +Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Производительность измеряется в FLOPs (Floating-point Operations Per Second) как число арифметических операций с числами с плавающей точкой, выполняемых за единицу времени. Итоговая производительность вычислялась по формуле: \[ GFLOPS = \frac{2N^3}{t \cdot 10^9}, \] @@ -105,11 +105,11 @@ \section{Экспериментальное исследование произ Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. -Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Обозначение <> означает, что параметры ядра по умолчанию уже являлись оптимальными. +Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Бордовым и малиновым цветами показаны результаты выполнения через CUDA и OpenCL соответсвтенно, а белыми отрезками обозначено стандартное отклонение результатов измерений. Обозначение <> означает, что параметры ядра по умолчанию уже являлись оптимальными. \begin{figure}[htbp] \centering - \includegraphics[width=0.577\textwidth]{kernel_comparison.pdf} + \includegraphics[width=0.57\textwidth]{kernel_comparison.pdf} \caption{Производительность вычислительных ядер до и после подбора параметров} \label{fig:kernel-comparison} \end{figure} From 089c4d85ea0723b4ad0d9a6ca28b8e30be39601f Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 15 Jun 2026 12:54:56 +0300 Subject: [PATCH 10/12] Change GFLOPS and graph explanation, fix typos --- Danil_Grezin/Danil_Grezin_report.tex | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index d49f658..8a99fe7 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -25,7 +25,7 @@ \usepackage{graphicx} -\title{Экспериментальное ислледование методов оптимизации умножения плотных матриц на графических процессорах с использованием OpenCL} +\title{Экспериментальное исследование методов оптимизации умножения плотных матриц на графических процессорах с использованием OpenCL} \author{Грезин Данил Максимович} @@ -48,7 +48,7 @@ \section{Постановка задачи} Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. Реализации отличаются применяемыми методами повышения производительности, направленными на сокращение числа обращений к памяти, более эффективное использование локальной памяти и регистров, а также увеличение объема вычислений, выполняемых каждым потоком. Для ряда реализаций предусмотрены настраиваемые параметры, включая размеры вычислительных блоков, объем работы, выполняемой одним потоком, и ширину используемых векторов, значения которых могут существенно влиять на достигаемую производительность. -\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность вычислений при их выполнении на графическом процессоре, а также автоматизация подборка параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. +\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность вычислений при их выполнении на графическом процессоре, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. @@ -79,7 +79,7 @@ \section{Описание предлагаемого решения} \section{Экспериментальное исследование производительности} -С использованием разработанных программ были проведены измерения производтиельности ядер myGEMM в стандартной и оптимизированной конфигурациях. +С использованием разработанных программ были проведены измерения производительности ядер myGEMM в стандартной и оптимизированной конфигурациях. Эксперименты проводились на следующей конфигурации вычислительной системы: \begin{itemize} @@ -97,7 +97,7 @@ \section{Экспериментальное исследование произ Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро-Уилка. -Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Производительность измеряется в FLOPs (Floating-point Operations Per Second) как число арифметических операций с числами с плавающей точкой, выполняемых за единицу времени. Итоговая производительность вычислялась по формуле: +Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Производительность измеряется в GFLOPS (Giga Floating-point Operations Per Second) как число арифметических операций с числами с плавающей точкой в секунду, где 1 GFLOPS соответствует $10^9$ операциям в секунду. Итоговая производительность вычислялась по формуле: \[ GFLOPS = \frac{2N^3}{t \cdot 10^9}, \] @@ -105,11 +105,11 @@ \section{Экспериментальное исследование произ Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. -Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Бордовым и малиновым цветами показаны результаты выполнения через CUDA и OpenCL соответсвтенно, а белыми отрезками обозначено стандартное отклонение результатов измерений. Обозначение <> означает, что параметры ядра по умолчанию уже являлись оптимальными. +Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Бордовым и малиновым цветами показаны результаты выполнения через CUDA и OpenCL соответственно, а белыми отрезками обозначено стандартное отклонение результатов измерений. В рамках сравнения рассматриваются 2 набора параметров: <> (параметры по умолчанию) и <> (оптимальные параметры, полученные в результате автоматического подбора). Обозначение <> используется в случаях, когда оптимальный набор параметров совпадает с параметрами по умолчанию. \begin{figure}[htbp] \centering - \includegraphics[width=0.57\textwidth]{kernel_comparison.pdf} + \includegraphics[width=0.515\textwidth]{kernel_comparison.pdf} \caption{Производительность вычислительных ядер до и после подбора параметров} \label{fig:kernel-comparison} \end{figure} @@ -119,7 +119,7 @@ \section{Экспериментальное исследование произ \begin{itemize} \item ядро 5~--- прирост производительности около 65\% за счет увеличения размера вычислительного блока (TS с 32 до 64) и объема работы на поток (WPT с 8 до 16); \item ядро 6~--- прирост производительности около 20\% за счет увеличения размера вычислительного блока по измерению K (TSK с 16 до 32); -\item ядро 7~--- прирост произовдительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). +\item ядро 7~--- прирост производительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). \end{itemize} Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. From 85e2bfaa567a8901c4d4cacb90e45c73470eee48 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 15 Jun 2026 17:03:34 +0300 Subject: [PATCH 11/12] Change no changes to default, explain what default means --- Danil_Grezin/Danil_Grezin_report.tex | 4 ++-- Danil_Grezin/kernel_comparison.pdf | Bin 85811 -> 85585 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index 8a99fe7..d35a552 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -105,11 +105,11 @@ \section{Экспериментальное исследование произ Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. -Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Бордовым и малиновым цветами показаны результаты выполнения через CUDA и OpenCL соответственно, а белыми отрезками обозначено стандартное отклонение результатов измерений. В рамках сравнения рассматриваются 2 набора параметров: <> (параметры по умолчанию) и <> (оптимальные параметры, полученные в результате автоматического подбора). Обозначение <> используется в случаях, когда оптимальный набор параметров совпадает с параметрами по умолчанию. +Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Бордовым и малиновым цветами показаны результаты выполнения через CUDA и OpenCL соответственно, а белыми отрезками обозначено стандартное отклонение результатов измерений. В рамках сравнения рассматриваются 2 набора параметров: <> (параметры, заданные в исходном проекте myGEMM) и <> (оптимальные параметры, полученные в результате автоматического подбора). \begin{figure}[htbp] \centering - \includegraphics[width=0.515\textwidth]{kernel_comparison.pdf} + \includegraphics[width=0.537\textwidth]{kernel_comparison.pdf} \caption{Производительность вычислительных ядер до и после подбора параметров} \label{fig:kernel-comparison} \end{figure} diff --git a/Danil_Grezin/kernel_comparison.pdf b/Danil_Grezin/kernel_comparison.pdf index 1b99151f55b3925a77e4f604bb38512a0a4e7765..c4d4a328aa44910c8e7589920c03beabb5e70433 100644 GIT binary patch literal 85585 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

Ahq$! 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 literal 85811 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 @AP&=@qeA{e>=G=(-5Y_l4t& zFfm?7Ys8yWPtXJ^Mt%*N>7BRlcSTS+1$*qsjnj_4tKhu(xJ5^;YS(~iIc3#EF?;~3 zbh=|Wv-Q=FZ2ZRdRE*54cGLWxEDMG-l(IAKV!(3Dl~-2kJyHAFWo83Ye<*+*~l_^?OM1bX4Et)F<;8LO|3S>@*ySG=w?M< zt@{e-Du67u7A8Y`Ghh21PkQj*Bf@r3R&b-jq~F3ZvuQ7}Ul*yQ#~QkXI1XQa33Yuv zy0>J^{ahSJjc=h+AF98cEle+Q6xswiH>?_;)Bum(jbixH-wTKYIa?JL5u7yG4>>Yg1~V;2g~kSsLDp_emQi5ucB@^O)d|X&fyorVV;YU3{N!gK9k&?yl3R zj0w-!S-BD?ytu%iEpUuZjSCYPM4mI;UcUHN=iD|sz&YT}z2VX&h`w>!iQJ!SWeWpb zG$XMGBN)@_#=V5N0}^yxNTRZsj$8ZqjRmk^0IOU~pLXx~1&&~?%^(a;_tg+eWu)HIhtFpu^vL;VaWE!Seba$syx1L0Cw*nO85t( z3g}qn=#z2$gF#A$zL+nyn}rRx8MXD%ZVCQl^^6^yQ8BT2v|ck!`>1cNv__N<*RlrZ zb7I_V(;vr*RASSYZhF|>(hqUnXzQAusEqCzC#)~VN(SYzaTvz}9|p1ki&<(3DDmOm z3K|Pl&4NSiK-~KCyM?v!%!@b`^=ee9DLdpt@=*BkN$bqN3t5CfhAG2-1g9%%knPC{S`%ak9$%2 zJ^|$oG`7`m8Ac2uOh}w*z4@Rqo^qhFO9A!9i0CJ`pKK^R7Y`h73u#_9Li@*yO59r? zF;SWJ%2`J6QKaAKrJdq-Qs2o+jAl9BWEZ;lh{M=IQp&9ylK+qv@038qK&K%L< zoE+oTXvQ$hX^YE}f{u=RZxIF{H^{rf^?n(X*Mfg-&accl;0+_iO5Po&wM@wt;mG$q z%LJ3wx{t5Z8*2SJ*c6^?7|~R}{yut;GYTR7JQLzxQR^7?K`0N=$IZzbt3^(G?)iew zTkX%EG;_>u_Oh0e>RJGRrWPlvVE zWoD#k<3oDWW!^{C94KmU62x9tHIiyK!hmzL>qPxlVgzgBl@wGu{O|%RG;ime-iY$M zuxWaYM;BGDw^jwiT!?wiL1zLod}f}XjEpOTUzD%#&DFYpJ5PIXCof%5YlAXABdg25 zqhvRq?`lLeSNX2PSCY#^4@*;;c`ebxeyRmmB+_G|pkLE5v?ob_B?pBepq^-CM1Fjn zG?DzxK>h9nN4z$MALTkR+0h3T)-!DE`7WW2bLU-GWs?vq{wuKozMI;1`PV=rL85sR zNp*eYu(~qyBhp$mQ*1=zqe=>Zh>z-nsvs{Cl>7*@(70r3*nU^B`G!H4Qft^LAozH` z|77o|T_s%5U2c+w)`<5!YlKJxKAs!AP@9}8KOYLDp0)vwDsaEbX`ToMM95{r0Nq8X z(zw5wo4Nlm*S!wP<_}jg>J4ypm+}b)c%#?sdT8h^g=fUC=iZ*m-)t)WmaCEz>UIph zIZ=js(A}NV|DIzMuWaVH!% z#X0)quQpRJ1~Y%l(^%^NpUf%z$MIG_LOfqXdlKnq@gKnSe-0;2hDJ|D&1N0pP|5#m z*d zf5!EFYJ0{}Nk~|uIVTJ#4SJ;%i1l7EcO_*EF0maBYv>yS7;9kJ~JRHz8F1IIKJ zuF5dCaOqJX@e$^p%5kTf>RX?D8{%mznA?F4&VsRC@(L= zp*7+#AY;5hwNVl(OapI*1KNcA1Hj%xHvZ*-wKLTSaK;o^VY&pLnY*uW8-_9+G|r^HZ;2Yt>HxN z>F@xS(>?SFb@z-YQh&ASkNe^8I{PG-2C#K51NQdz*1{f>_zg=ZIlMz9-$Wz`9veB8 zDZJSNXP8IoTgz~ULufXLY43P*wzXcJ^RL#uj^sS*TJ!V0-Ke5RWDnlTI*bNoiP;or z=`2jAyMrHcFNHTCv=fDk>GS~t_U#>^-Qz)sOj-7Q-bGi!IlWm412Eh2+#lvZ^y4aujjFF^ z_%<;Re7y_&V`I)gZ|xQD@9p{wq;hT8e&wY?h?4U}2YNHAAl_)FJK9#AEQ^hmwT5MV zSoSr}O7}at+y$u)o|p3{Cs-CGwnZ}6=eWeS&rR+n0Bf6Ix5{+Z!2N^Bg*^gChCZB4 zoEp@f8pHA-5=j-YSVMp!$Cp^#PR|_oX(LN?Zdr;3O>g#B`q}*2qm-6}?`ii^!a8Rn zgCl3jNKEj6b5obuU5%90_4uFuSv8rFAo|GRd2C%%UX|UmAfmYo8PC>ee9gMqG$V0uJ3>??wU=AHco7$BNZVdW`asojSKRCpZ3C`{ExoVfnM3V$6(_3YJ=a zNdw*D4oeDcYX(dH+fggQ0D~9uxNsV}Tecxs9>K91^Tb+wiZMf_-7QFzuY)7||7wT* z_sto&mb{R$yIyP__htA83JSqa5e9?@!GNDPrI;raWvKTaojWSMJ)XCmcIxX&72Br@k+Gzgn2-vIm+&tfjfh_IUZe z7x<7w4a<{mg&Nq=KEK-e7$v)L@~yx_FNnoyh7XJkN$!0lMe9@>=r${`!WsDXtL1oI z5`l}_i1tHOsz5_rfe3oUjN0kUmGH&K|X+t{e1{!H3&+ zuPO+t20?Yu zwbt=RxP?zXO5-tQ5}`YwC}-*p5<>wL-7r75KE=zh*il!jjM=&q6KtWM+_-#N+# z2Kcv~Y(PaMH^LZW%g0jskF`t6HD?>ZHFp`zOLC5pTgsMA)b(R5QQK0?RJH0S4+bU6 zrs{DWMM+X{aZ6fp)>rYO9G?jVjQ3k5LR6v^{pDvZL`B|=_bq(3E2d6jB6v682m09)o>QG?e6~ZgM!uqgwBKGVV$1rZGIFmWdOA& z^+$PUybn*!ze69T0D{XE5O1fPdb{E+$C7EfYGr<$h?3BvELT+GTg#Y%ppDpmD{W5! zQu+Z02R)6zwNn+~+za0-x zj*F6t_j$i`Avg3{ZM84EA%Q^wWVR2293Q^*WQYzUBL-37hyaxw13m z4j_JDyuJofSu<2g^h7hGqF$55RIl!sfcX0GZ&3MFXbTe!;+IY?f(l{K>Dhx_$G zpbDoMYwo@C@n!DYHeF%1QK=KbM3Jg1AH5l`$PFW+{sSG?G>mI|X=iLAdcOByGyAPb zDn<<-0`cfJekI=S#JrQAzCfaUgI~{&>#w*U+`YB{u`wf5N6HRBO*Xq_`mLBF&fO|I z)8{i(nkxlVi>02MyavaDG%xp@wFO^k2BI)45y`qZWyleJ+m_~2=s^FTuMt+G?{eDc znQ{4%Q$qV^2KH{RMfBBsJ15UjXCqbhkC6L{^O?`UkSuDAUM20Km)*`nVtTKE3iM}} zp7xIw>u;n*4F%jy>tyECWaLRTw-jcyz*+5cbn;K+lZe&%Xgw$xqelhBT|qg?LK#&7 zqf)d|=|NO45Vpd>FNLdJg&_n*%OaJpj2QjDT>*&U-xN?~b2POqhTQ!2%mT(`tOhDx z3YNydVyrm^kTyb0GgEIEwMU&8T^j?AkM_L^^9|o;oIH$B=TnRxRYNWbVr4F|W4YHt zy})L%6#IOrmd;ha5@?=eL>68&2)#9;+$R?evJ{LtH(Hsf0RP$J#UC zN<-%WE`P}gd~M(%$DsZ=YJkKYVryje>-V2vo1)tS~9tf_GxL7xeEB^5`^G2%!>IquODcIaRFWvt< zs!F+MMR~Oc1HuwSAVr{!YAC;X9kvzL=HG1fIqg5WQ7#NHpLTz1m*8SMlbl=3AwKA- z;i~6u8=QFuHiFw8%||1W=aBH*a~RMeODMKyFh`hIATm8Jaxw!0$T>k)a8GlQ@^@K= z{~<$`57RAm|1FIy_VTruEFOQ^^V++TUzz@;dz+5u{<(<|Y0jP8}N zy)09oZ~Ih#`1RW4O1@x1K!xD@KcB|^VGS0j*6+tIoP7s@0TsCW2mGCMZ$1+SP~yN> zh5OB?T4S%P;R{4ZE9mS8>m30^$rqhI-O||9Qd(pRamwqjyuH!b;{RliQ%PGgjzFD{lW%s$YqVB{EJi4!|>u>{Jye zroB->Qc?SoKv77ZULP%AtNresF0Bb* zQ@TsggV;^2?p;-T7*=ua5sVA5L2O(s461Oy8U;`Zb|pEty8*782m^}RBte4|BfTTS zbC}-@zUDG)OXeAbkE*2<=3Y8V$6|PX8C{E#aa%VHQvqy=X=2i_l!A8zpDoQ`+73fy zK7TTBilnaoPQ-LmN;*TOMv(0HE<#J_N6W(>?Wm?k3zG_{9OAa-9=hN$ z@P1~#V4;a|VS{++Fb5ej(r7|)d~Px>vyqfVTkY4G9=uh8(4$B{l;`4rNrwO`sapI0;do`y!0eNrS741=o!)_ zACJ$T+f*mX2|fRELl#v1aQ3+oq#XY}#Tn`+roF`*+A0nZ(i2r4@Cl|ag`X%F}r z9a~}*-qiW;?HbB>lA1;vZ1(%8P{!XegoZ`tZA%>(m|MIq-0e)|doL zAq_&=#J4ZAXDqn~&ONJ

{Xa&QM2!fgc%lQeJdzS}Pe6n+deS@ZAy6z&pwNqo)z^8+t&JOz{_%46mQ(8OFb^gWm9g!s~>VXDL^ zf$;<6R#eoxDa(O#=hWMqk{wy`N+;!(Zp*EtZ2U18U^)fYMs?6i(C>vSO^`~QlfxHv z^}9qf7$CfJJ@iKb?w>~OhbaYb!+;8F7_c!1(h~W-0QYK@bcebXb@k3|enBMpd(Mbm zAXCTpnz0btR{;Z3o$t*5D6AQrNxMou6L$tpRe?_So57U7jm-)&D{Tyn!b0QH_Y%ltiu`{hsO$o@9(4yD&w z^_gEX>Y8_FM6NFM#>0Qh!_+AMQ-pFQvWky-=Nb(I#9rs?8k9lUf^K6bi!`u2S429M z{)(=f|4O?4eVsK51CEv~U;rZ2u#WOK3cpNFmosoOs5(|UwtM`fDSAIl?!S(v|JVWG zH~~7^gBxo)^3V{ELalkKN>9?S%(DnpOupDeEUi8t)nui+PYo5t@$Ubv`!fG~G&ETL z0lZny&t{@l|HNw)A?vv1=}b1-uf3oq?$Fq>km>`66RZYIicYq}jzaCE%S!Fk)f zgclQp2p(w0OsI>Ntv)mpG@(Y}>P_OJ_X_&IAzTfjq#w3~em8z(DzAOzBsydV_jj(up+XcOG z<}?i(h<2x;eBCDwhVXABz~nGhEC|&qmaTPtozLKFN98^PJ2u5=7mcS#V3TS$(Q3me zQY7O8+=8!kC%i?k#<-B0c)Hx*vGhCge05Fj0JEQ8A1EaDH`T^2zcKO((+IaUM|Awb zYo+T=cxPl0WpjJKPiOFHoWx<)bao~6(f$Va-h&TLQUDUc+trQWABX2Tb#h?x(IDfG zg_4}01qmVpg=tIII_q+Bmh<&FA{c<=FHLcohV{91{6tSad%IMt+xB4Df}-!ecOtgI zgaz4qWpHm@vp*N_!Rh5Lb@@GwlzEXS6mM3nSS3XAie=9jw^)%^Ud zHp)s@OaHvdDz;-o4YDUEBw=M-B_X3NuaK4 z=3WyU=}*nS`;auj!#vhIKo+GVwTJ5;Qh}?2haM#mLnrtW zaDr0ZXOp78?{#q^3{8K^I?N5i#b!%pHROF0g}}U}+91q*Y19g)y7CH&OFbawEz%Z} zgZ?m!?LKy+wGT93rK+C5cf3)2)FPkLT5MWVds0j*(wgR#c|tpgBJ^_yhbKVfFFQEt z8rMP#lcxe#=yoXU2osbo%#<@daHZb?y@9WZs!xkt4Yq$gukc93Q{y?mgeyw8%JPN* zXL-;C%9CBtK{FJh&dzh)CJY1KSBM*d?82|kMJ^U#fL8e4(I0RWdq3>p-9SL^ zyzv4Jz}?{{xL-T!NcHa{BljQPV}ESRS@1zlBR)^h3W?LG#C2D`FU z<6u+6PfJ!PWm^!%+ixN}X?%Tv!>PL7(xs{wv$r=&B=X(xT$Xv%50mL^hj*x4D9JG3 z5i7Ap)pbC$oq3L`CiBY2b|Ojz*`KZCSD1yzF+O|VapMOJ?@8Tn#1$9N1o4m54LjY4 zAnMXgr;jcMqpf`nkAD#My!oOJcvq?JUTA*p)%38+N5?6oVv(uM;3M~F|E^c7V|e!4 z(bLbKsXE@>rU zIhNbvmC?bY>Z3Fi{V;oJ-L^6C#}t9`Av>4Pj6|`s_hw#}>dvOR^7ip4LG&&qA%x?c zp1R!2#Q4k)6u3`TUa%}I>L&80UTQg=U)@&NR52- zCq#0zxXyE}Omk6|jYBBkM9|;MM{>?8-WK8>Xcguh)lV@`hd?BQi9YWMC`#$r588AU zJ8dde=y|8?k1sJ9oMc7OJ<%}6!V=mn8}Iu>QNoNO^nbd{prm)+u>$8!Au=B1?!rd#~JwV9jY7kMNHRP(SOd_)@wZ6hjr zmmDfp`WTZ^af%d|c9DU{oCy6t&;IiP7!YiG0d3lY0jFq%JSbI_O-_vPRp+W21`L|y z_^2ioIMkC@K2I4Zn<$I?uqA<=ZKbHZ=M@Tqd)SSa#Js{^^sm(*c%FJx&;jVhqVeLj z;)gA*QN=y44>uw=3-6Yi2R1jq~qcpkF9^QQlP3bv#_ZxXvpy*v2U_5Cyx zbr_PDIemqC4!USYq(dDJp?p35{|U&wqz}+13idF7c@-`grGmx(45t4TK(vx5OSO*X zU_kOegHVzuMNG?9pc<)nL}%*%cJQ7bB#(<*T0D^6QYEa=kMe>C7cFbqXy#BDk;s2ext1OYSEd)LztHp)H|#K zZ#;S&Bttk*AL6d>TmZ!nBRAfDOHmuaF z*tvf6bkyIo`jX)*0KTUyprrfq%~+0#-}vr=M6a6((t%#9s`%*7DAd?^b8?#%Iz5O5 zwi|b50JedSKOVwdRiT|p;iY|++x*mN4R~L|;U4#zzBii^nhoaxp*cSnxLc?=m7ZOu z1~_Kx;=A>Kho^utSCuN9S)xPg5{T2U8xqZMkH;A~sQ81L$uRVBPBl|0Bq`3|gE&L& zj4w7YfhG>PCiuj1Qa+Ri&+2MHK2lgm@XHmMbv_nFOgU@QmRXx`6L269cf49pgY(dn zS0ve5KjLG+)=8r6C~}?SBC70q!^c@Ip9eCqlv%C?uOV}o#4E1iMvrl)5RTU}ODe}H z$|&;Z?3k+oiw@n590y^H!oC8!=mUC{R??5hY}(@^hHdMW(euCScgkJA}lsNRC5M*gJDC#WksxY=5SjuYaFS2N@4x!hAy5^0H9X{$uRW$Wcr?vXPsq zan%t^JZIqjIJPMHoFzq;Yj78jtJh%AXOKC}o!uVSZal_%;T4=BzycnWaXH$Jfcb zS$$wDyq>3ks^@KT7r$sxv{6&dBkL13*g@~`!GLUWIeX0PQ_~ZT*X8M6wF%$10X%yA`HS4ta-Nu-qHNRjWWH1 z%VCTndk)v(-QmBy6pF?!Q99w|%?uv6(P_#&&iwVAam&tVLmw9Xas~8f>%3pzO+CLp zW94}HFF@y=zxmfd&cEHb!A?v~?3+ooHVrqSf`eioz_Ztc0akINJ}TbDdWu(yyI;LM z;^NcW$kaf;utfRGJI|+-Z?o6U?IrP3&uhIU*Cc;=N6{5Hk?)>Brr2h7_eVb>{@1>oD=$ zGar*9y^KSGO8D~Cc`ynfi!*hkA<|Ar!+`rg!U>X}6qD}07hJIqzcQ+J*{+NR{SaEx z7HE8K(>S{J1tS2_$vz!G*oyWuM~sdoHn5f@O@{#%_HqOhNXBB%$b(+$Qq&R#Pe{yx z31WMto*ytd#2D?PQCBy-eA-AlU6okWW?>uqJQA%@BXQr+pOyqTDI+a4#0h#^LoN&< zclALX#qD@GW@{^PXBvrNMvnCNth=!<-U#G-Kmuo9^yfgY^+X%Qh>hDqtg%@YX;@~`?6GD};e za)=>mB1+Z=X{dH( zo0(}JmSwbgMJ}DD-D_&D#_f(5p(-H2^dOHRTgUD)hjKyjGXR z+-rv{_8Hy0R3l6fONJBHd}9T5)vChg~S;5lTk$4o$U;)AM2URRo2!!^Q!Auh@&&*^jz%y zz03#ia*@N9dG~^W_8Le{)iHGFQO9~(B+mm|<-u^v65aO3EKC`_A*UUyFXqh^hIi0m zls2UOj^PShCjqq6`ufIa2Qj<87P#9~^@B+!Ql|s2fsW6wN9oF?AVtd#ffRhKh_!21yGH7wX;h*4C2xF-rL}+PPd5Mg3=wfmUZ{r z;h5=5a7StA`=}sv{yG=liN86I&Q5Z*!Fl+44gZFKsPj(TxhnRW^wLN*;mX!)tX`3( zjRZHB+4o~gV58ZVW%b*K6U=qs!Zv3DPqIC`Tc<%(j-U56AQ_w~jn0P7M|jshWCq97qhz* zy?x65@QR+hmaB1pJWn-Bh1|J#81OG(Q;Y@vzk*Kfj=mA;o;kUyFWU>Q_*XUgPo(Bw z1v+M)j^B$7`D$F9*7IQvRHE?LT9x#f)1}w`!n*^%!lwKMKNy| z(C@qm7AnNfQ{L}|0lxqr`W63RM!03mHr`Ez$ggBOdH;V0J@zRh63jfLzAifxI64;m z-%ZZH5_E~D;8{F)KULex zOvXIJyf3o}y%?LiW}6<-XZU(};m362hu3c=9=#aC%zc2DlxjINCMa#;xFnSx#B-kA zYX9Bk_JquRW*~pL=9(U{@`LV3=7blQ(+E$DfqA5y3uTNi-&WV2;-$9U$SzI8XXTf) z7W55}pId}IBPYee!N8^s#5}Quf2?t|Xdn!t| z5kddFrqD4jSJ#jzxp0hY_IHc?%{X=Nxj;rJ{&cI4y7G6%2~;kMLigO6O&s$&-5y;; z`}0p5Y+oKsP6MbZG5w07H%0-xPU_>A;BcgAGd=CUG_`!zq&-VCD37rfo#>B+Vz@#Ks> zx96AkT)k~AqXn`y%+pz%k_jb8!MkTqN1rway~5WwA3|}Au5Zp^jDhzjCdtMt$ew|n3c!x#2xVzP-Pt* zv$vWk>P9$wM!dOBgG}SP*a|Wn0L*?z>1DlB8w}Bruvd{Y4f{fZ?VWeXj;e?M=)Rx>fM!tc9{@gf@V zUCAetYK&ZMkEGp1o(&P&5eebY2zHp1o2f4v7r9^K+p z`WoM^l5(Hyl+(h*`j)(ScH?tg@G#BYGS)g=PWT4JxmK?r78>74303HPJBUTn($G)g z%aE;w-toO=_#96J-JxiiExoBSmB(7Z=M}N~xyNn__X7F#t~M8vO&GlTH+(1wNfg%1 zhchY!uRt4_K2GlN6?8!2cH29e8#)+hBp2L!vIaM$L$8K5dSHMM=?UEH`>%g7mdXZS z@?G}@8g|Wu%HXczT{>1<0VBsi9MpqnLo${1_SCK)?xo(mAP?pL=XuOf*x4fI-$LHU z>6@A+f5fHzTdiN{Z%@XL|DE4|vgd^y0vL>@4_vu#lg`$EW#+Srn%Qs63I8&D;9mUs zM*$M2f1byx+VR9Td&C-kL%1D6a_5vi_N+{1r)2wmtp$K1T*2LrV7f8TGYL{Rz%al|k@ z!f(AKVSo-?_YPU9GW?4Z?7th$>>nk@KZhb?+uCKyob0>OWOXG_@zwBR16Oz%0WHF6K3%QKIKEAz_QfIM%03Gx_$C9`OK@VFgg2?60L=C8b|~&R7(?MhGL%I!Z%aG;?nAc`rC1us@Ls&suGq5g zv-!>GQ2#H4aaG|+kCG(xfHI0XEABe5+Ok#2J&Tdq?&I!@69QL5X#sJ4iwNfaTnogz zDbrVWKR->V4@Ey_oY5v4>94E(^aO{FsXjnd_;UR-48XSZaL%i%s}@7q%aK}>zL)w! zC5dE9X?>}QZlMeBo_=``o^Oq4B%qKyS6bO~qs_>QzWr=zreyE_(|F;D$5&eT%E!04 zNsn$-5PE0e1okI#XX0ljN};?p^3B{zY4lXlvW<5ykkc>o?Ol@LzKBd+r> zmLWbo2I>7-o*<{5OnLJ}2~kj%|K5_C;H*>&`SttJK@_@k>*mSk>EP`lw1zkZA7kE5 zy2+C()hEc441UtQfV%inuk6wRjyBKS4f`A6JQ#52k-v1GV57~$SP4*>eMU1u1_NFL z`Gpq47V5{Eebjt3mO#8#KgZVy&=kvB{rtCqT=l4CDhGIpNs z$^00xR7-GjQ75RD#=)tj7T1^Rm)@ZMdBR`btV{S}jAm$K*rRc6{uvM~Tb|~W6CqB0K{i2%f?PJ(o#V}59%@84!q!%w?QC&;+N4F< zK(@HIy}K>TQ+H#NA7#9%-&fv`7j?KA*eqIEK0KTh=H?uuN};76uqf3YHCYW9t~Jg0-bXE=`ZmSEQ>)_Q58iO|R-dpzuBpSn;Dr z{G3s5RhGULwe?UqBo5Qv3@N%Y>UsN7|11Tzk44orW+h2;5OrAJ!HgW-i}Ez8IY2Ip zu8#IK|JhJi`3rH>9H>A{L2tO?{JYAC$($u3OC#N4cTGv8P9Rz zUWl;~Cv)_W*rE~H;utF?^ri($UFD;`oB#Ye^8tt-SkHs6)3YPYZ%@RU!?+d1dy%5- zZ`nshCS65NhFO0G)il2}gNpHo-?{#bn6;e|6E=@ucaZT%X$^Y>C6I{lj1nU;4L=mvcQ>hbcI2%W!|iv5E56ui|^jZ&dM z{s>_Emm*_YMwkkvYVIU_eJd>nZDjoxOZ1Q8CVgfM>c0jx)^7;&o6G5L2&0>X=1uo= zM<`+-;$(Tkh4K~u%(VaeQMcJpJDT7jtjtCUP{{M4i)6pN3v`5AQIBs2F4e{Ur?dV? z$YTZzr_X^^0aQopLQ|_N(b_7C-5<6qZ^-`MaCJz#1`BtH-1+}53&p<_e-}&H01PnD z`589$*Ko7H7x4!bB^j^_Mt0#1Ce`8d<+l*Ie-xeY{*~B&=?Q8$N@bIwedf%~WM8SNJ8}l`BC!47U2uL ze0g351B&TjfP|1rq3fSMyZHwjHQG&EHt<@6*JH1%y@zL@HLPc8=wJRpu=2m!08;y_ z!>PX?a_k?ae-Z6m6Y^Kl(D8)c2mU!W?Z}ys`ri4q@eAry1K*d)3!rs65irNUxa>%i z1p_|DfR;FgscxQqk7$l=zDsVjJn${SOqvFdc9xi7Rwq;09TXx`t|YAFJ5Kv@aW*;} z$c`;2%9cyB9Pp8um|$MKKj$j5SZ2nSt0TPj@uyYyB~LH@EKy6eXjsee^RHB#lZDCA zW$BbkW7nV7-n^)EbT=liw;vp_hIos}9^n^f=4$kjJ$DX}t|p+xnV>lPAPzVQQyy{F zQ8l66kI*SL>Vg64bi4+qT?H=F)sbm>TVNa`S0)Gd_^ry+qoM+O#Pr10Fy~|rB|qwL zqX&vM%okPfK!T&WZOFFrODo4BN#s(Yi8*Bpn~J(aUgU2iK9O%aA0m4 z+pfKWJ`F4TRyt>{2Xj9+i}T_zBXmc2^h+KQQ_arhI98@7cP2<^udBDB)`iL_S`}V9 zl53BDMZWTb`Uu6g73cAC6yI%QC)SH<)NG~tvDlTDpJiq2iNdxvkhn!303A!3cnYX8 zcFW-v+a$8n(}?F7dKK&hFhJwE7~futisO!lmk0BHe6GdttGG8I!!q3GS90FKPnk}P zp1t>W%zg8C>RiArjmE`w_uz6uIa80j0Q$JOy8K3ELP=uF@Cm~$t}BWX(aLlK^b0PQ z*t#$Ood?nBWaXVIv!2}8$D8T74R-QOB)(Y(zFkXyXnw}qh6&ls-Z)3&0n~FBciuBFVDpihk5A=j zQCNaTpd5GEr27$QKm!IGq)Vm}-kya+ukkz9Lq^s)uUB?mD1HN=xX}h*EscK0lC;0d z( zq3t^z>bvhkTYu1M`Vt1<=85byq+X+|>iiF5=}*1)4YgMRTmGy51bG4kZi9$c!hrWM zfbExh{C2<9qyGzmHMc_vzx3_j9;^Qag1|TIP?u%cvWxDCPe=O58nS9sWfjmzoZhL_ zrpsk8%;!#A7TUqtO`p%(^H&yt+CJP^nC^hq{JfU>4?aTp-3Ta%`Pap>|Lcz%{>ww! z7flcU^)^zv^&j7GJd==p;xeH%HXpjQfR!xRfmioMjolg^qg&OwAZw z&e_+5J2>hbeB5=ikyrR2Gs;{H9TEJ9X7rU_0YStm|1=GKTFoDGKh8dHep_)$`#XK$ z)2Ci##CvbTC9CSj_c-SSl*3kaO7#S~jnU=H)*+`B)_V;&d62XGdSAVE!Lny^E=gp; z`Ac0krbpvn&$)A^AMr19JofT=>dWDLN1}_ZctcyxRG`2wmFhftN?i>4!SPOz{(5JC zBqQP#-2pyxwMep!vnj!BE z5-Lp~GOD(g5iG)gl;p$L@!B>!bHJpeCyNGcUHa8)6(f5g-djuf>|GV1yYr^JL$B*X z4-e53k*^9LAOpPydO+wBTI=Hz>eZ==RTA#ZvE0Nn7kb!gyJUdG(UO|(#!n@0m5}qYpP`PUw zHa|Tr!tTC`YRM}1Axh2-KXZxl^5h8h?gK3h7>q46C&>oKK<>ga@k-1;}e}y~AGf>^%oQf=X6T(1}IHN&kQA(PuS%OUXyPjv6*l7{X- z@Pz+{nNcm6>BFS*-ktZl`tNw?&R>a`9eZ_gAIv3%zflXt(?tCzCKvB_#9Eb##uPtN z?RF0Smdrm>o#Wkr^xTu2f@JGnt_zR4=sR#k5yF5^Kf}@fx04m~2Oi4bFsp(8ZE{x< zj>KpolaOYkuow`KEGyf4$a=Iv}`UNMrQh>2> zYIo(f73<~CD9gp4Z`%l7I9bfVrNUd7=x$^C79%L-nGvtC^LNx)75qWB4X7luGPE8f zrgJB@_CJ18X57Z&um7QLunOsq3r8+HiZykW6;)qK;!ORizil9`ZX6Y;D422y|2CeYvO<%xU#7NgVD zsYY#{7By*n3Bk>Tz6ilQVuB#mpWRZ8`~=WJQ;*o)Eq`SkMhbB<8bg`4VTqn z!|SnRjfOye#vHswcR_zHMLcPJV=bZ4! z?)dn$+lxdpNCAgbQ;7WuI@qqL3;A?H&!`k6a3KDq{Aj(i8MwwGlPc`+dX1>4r;4Lo_HB~#Y%OY;r9)Rl8(C`YF*kXt2*D<++cJyd zaYOYO1$0_KL+ce=1KYQZr%HUt{Dx(lX_(0`Th*__QqR%6g7#kdi3ia8F+9W;<#*~_4sBJEAmL+|UXv%c6qqwy zK9JS;{}^ z)g~zh^L_QU^^uhQ1G+hMq8z>`1wya5dY3~Kds}uKkNNF>2Pk>o7@e! zIrT2rV)d%Nzi-B|@~qt|w(T#0<;~X(&T11ue~&%kY7v^8Kd9#X3pwld67)ZtUXkCG-n5j`^3qeezfTrSc1|_&=d?uu==!-g)*Qmu78KtXS_CVzg2ttrQwl6&qvsx8>O_ zv>mGkYemFV=`$j`|F>SkRVfvF(%1S<)PF6~FC%PqR5gDo^@`XDZY6~Ov=V?TL4l$+ zQ`@W&TLOIRN7W1D{AW3D%}KyPzH^g(50m{mYP{ElnjoVVgcEv)@ovHL!m`WrJD4>` z)dC=f-m+L}FXV#CuwJEOLM8bZ4rpl)Sa)Ye@}xs!4^Wi^6i~R+pMGG@x#OQdpI+sD;LutAm{JEZVSKFUmMgQz&c@y>Po8n6gM(kE zAf$9a7Q&KF7VXBcz7GSW{JNd$LaB|bj^pEy5}KDa&$1K7NihWms;!88K&7ALpAGb? z45H|LtizM2$Hkqy}>QnHdBm!Yh}<45jGLAgvp_4 z89SsMhiA`dUAf!j-@W9r**2XYZ$D^@-AzA}F$qRS-G6>57&F)dK%*kbeb;pZzZ z)gh+zBbL}Ib#?}FhTZN}7%)(etK);DfJ~Z-si}3z3?Vj-yAfA=rpeBoA+PTN5s{`;oNx353&-pV0sj8xtUZmRRIrz1_= zucpSYuC^!A37s`BPs*WDHAW z9uV5eA3ei~kO*yn6;NIy0MJ9+61Tw=Y12LBIzWoj;HC(!>5guda=`Y`)1`hXa>(?)FYlF zJIEu3L9FEJMoXBii=G_bdIU>GTG5tuKF>Psj*P(6oUqP1;t7GaiF=q|!#(_xBjEc?J(Vvz110XX7}3bV9*ss?Qx&fD+u)To z`>XJAuv_9DngwPk*ngHpH(tOvfk2rtrFd#n-qN&=`%@8vZyw~b;d~V zFjPkj9?eh5;JsS02YkJ;_(}H5k1kilbw&5Xz z+r(eplZ}W$NNOjzxdf3e@RmK%cMj=8^tZdE;y9_{<&g$iXX~o#FUK8r)P3$8?;ovU zAMUMEEN}ttOO-X+Pa4>GrsjIBp7JuGNP+FJEuP$pXMNAteq`tNJx2RIwd24@a5Z_+ z#R7JkjFfSF`lwD_Ml20I+c$8T9dmB5Ah{j?mnZ>ab>&g=K2aiWC~i~J@BtTwlx~%L zIngNgJd2c3(s`SDa5rh{{kh)KkM$$_>V39*q#^ou#2~G~iU6xr3^zYUCwE%HGBy?D zAY$8h3{}2@%?~bPvKH?f%7Ge;7k$1U^#1%XeCX1LXnp7mIR=qF@dyXWGW8qb0jT%LaprG%p^Bn0S>&!Nbl_)TQ>WX! z-wOp}c$%pH8U)GbjC!nQQHdN$M$K==g6Ye#q|R^Ao2Sk}C;O=}l)vR#8K0?E!wpN$ zy;E;*a@Qn(%hmESI{9cO3xAh^;_n63f?ojrZPuASL_4ne?8_nac?K^ElMrVF6UzSi>5W>DuBxpGL-G?Eey*6bh-+zC zodp9r-wr_Q=}s~_<0YPPN8Lnr?No&u*yAT<%X}*itvrfk99MM`=7rl*0if$GR%ocl zMj=P%|MtT-2B}rIEKO<`N#%&{cap=I8NN)+eLtj*i;e>$9`2H@z2Avm5ZWpfEW~&L zH%mI1-Ulg3=H;2EVHSe5cnDSy>I70yg#F6*_URyBWUV+OI{Dezltge8 zhC~U9&oE||G1q1~ey2ctq#zQcEJNJn?LibI{eT+wF_vukZvF&~&;eR`iSX-mKFW=^0WIa@59DB-h^EiKHR=eZjiwviCMKTnR}J& zi@1rYnBmLJe78Jz2e#cHUTy^L;;d&bkj2uF9@1hIZ zT!yY9^|Q)gfH%=Y$u$M-h1tnInym?Sf~D}=iimug1$?<+pnM`u-iak;-LwW(*up{k zWJkHD$TF&Zs3-reH0cBO%6&1)H)GTx0PRC;8X7RWFH2j&_VXFAE53Q~CCL~eChg2e&dnlUcYybyKu3uOuU*(g(e&^^oc`uv=1q2@^9 zu=!~uKU%s7U^Uf2nkz;eu-w#2u&B`aw8B0!r`>>?5gB!VG5p;-%k1KGPt)S6ILB}0 z@0OpT@81?+f~)OO?TVj$K@b?=%zhA6Pc(|e)VhaQdYZq_Wh1eVgE@9LI)wF!wy5Q- zz`CfWlZJ*mQS^~CXL$#SG-I8_^I(mL4>Q9>Rp5M1`}9$kV2S6SH@FG6wp8fTFx28E zV#Py~M-T0Y>=<6uQu@=)urzdL-MpDM){&U$S8hgysKNU|Tkoxw)UcNB07hvGrvpB% zx415JRP}JhA~F;0Y0XJ)L}~-@qhwpw`2CjL^vp~B#Z%ril%M`qW7b>m@E6U|rnj@- z*pfgGDi`)(z_l}cw*8Ex_!h4G@Yc>nHh$aODfPxAgs)hku6EJ}Cmk@-_ zFhH*P5(dBktulBeBH@7K1&6!Fx9bDvFyM|K2CTp{OOZddQRBu=&qN&@a-9|Wr?2)i zjHBHx2nK+aV1P9Y$hd-QJQxt0$ksfwrNJv40M>^ACPt{jAZU*y2ezGhE$9XWO$Hso zfS(~AVZiAQ+^dBFXN9D2s2?`X>-Q<>w0A0dw_!8H1949=7e@PdW9kNmy=v)|&dCUW@W% z@7JM}M?v+yvx+MG+5#?=B5TT*67U)MizKRj)}^dxkF}oCL7_rQg|7OERxBcGzy9H( zOX}-r3^w}gX>UwY`SdiV){HNH&z=Rn{$FZ+{POKtM%7_u)YiG{gjP&w7GbbgCI?v* z8qqh3IjiL2&$+>>?qWprOoC{*PV6SAJNZ&p1C7bA6{~ePD5{ zae6#F^{L~|iELv&x8exDXr5_wz3B-P7t!0nQnEJUZ%U}8_bRJ$wSXnv~7Ya^+9c2u4SnVnMkx}A5x_8^`!l5c-lR55@OC8K6V$G5HeCB z&Q-JlbfHY(C@UKodH=_ddNrk>=eVzU4YcAsOhUuo+cD3NbL7pmA&tCNv6YCq)U#%m zOw+Z9%TyRS`!r;;w-24eAfV(PIiWx69-|#YhQ43^{5fCImSyezF#Bv3Z9i~&&zBQo z!}4S02SK5g6`t$(_`~^%jF9fo7_U2CF70pp-qBLkbupEWSrcd$NDlOmzaDo`^xSSs zjO`UcKv=I$f@MIvlY9HV)=P3P5f45nkrt9t5}IqNX3yFfhE{-g-LZ-4vtnPdNv0gTPRWm%*&*G6$>qV06##$zn|m- zNwqL|npr$6$T8hs)~{1J!f=nrWp2Fs>=Vr}l8Bc{-5fb9LS?<4uz z(s4-FDNVL!iv?AbfSHtU6nk1kTiwrauu9w(A7362%v?^`m>AflTb=AUSaK^(i?2)D zto0X-5Fjz^p$c6Uvrp@>oIjgME=LtfF-I(`50@7fsu;FA_x5Y&szOLa?|meAeQzUy zOWWd6%k>AVY29r9AN=6R;K!tVb0-Ml4K)W!x)}66Pv)h)27|IuwB4Vs3+?)*3r}%I z%Q_SI=eI4(zL?&89bYN-E?RnhLUC;8QL84+eZ3Qc2@{;@oQa1%cdxQ zl=<32Y16`qFw$aVwv0_;$u`&bz~#LA=p~M!u!>S9(Jr^2RWb>2^xpdT_4u*?z1K#R z(4;}cb9Pk0@&3fMtpyy`^oIDySQj|%QDpQ?L@e^T)ER@!vE3``!>lY|qlEp=4!jhH zuRW^|F%ZMd5z(Bw^j>+Zd$>R2_02sp4%yh!Hv8`S%q2G3Qp?MggP{_KqspXnAeS;! z_GVBqtoTv`UQMJxo`4VrtgH)1taRxj;1)g$JknAbk=Iws-xAt0&CnB={r zO`$HWO8IU}*Tf-e>q3-`kQh=;@ljQii*Zjxd8oheX$tdR@vC-H5vD7zkf=u?sav81 zw_HmLyLax@mIOSHwA<)Y?$5@C?9$YbmU=9gIknxme&Etpr{oHWoNL?WI2PFoo*h2D zxqMGCX+6yAT9EfFRZ&z5PTHf&I?0hA;w@Ox!Qgh0?Tu~sE8D&Ah8=2)I$WSbu zc7HQ}--g9TgL$l>G{c!tQOn?{;8|rBqx|2$m9cS+S`Cc_tg4H>D`n+R=y$u0)kV9 zr>%POz&4revWzz3fZqvV`F#Sb_$Edw>8zgF6i&Sb*T#Sb{@v4Q@sS0DV$Q60(NHozwh$#RC27f@Q`86_t2t{vDF86JF^e zJ(!-ZhoMDa=8>_EnmxSx4Oyu;Dq%WKc-}y+T%MFAovuvs@WK1ACf$Ks&1d$Mw=8AP ztf~s>;wgsQcVY0RDO^)cg;Q7t;Tau;^u6!ld&0eqs^-kJqJ6*HUM4*s*1srBvZpHo z>Rjc08$txY7Y)M(X#ChwqB|@d-U98-O@;i}Il`?$4e7hy8!pvtA9i=WP&c_Q`4Rjp zA@4fYZucF8Bla?J%wHLvboT+KH5b1QrO zQdwX$N{_CV0^(1;MZ2xb~h1v%V~2l zu4R1u(BUdn3(h(}b8T@Z;(MJtaDaQOIX8ge@ZWyQ`>qGZe@mS@fv~qXfctR0`T1+6 z-_l=T|5-5<$@2tT+HTHs@6Mi+m7eM})m)Aqw$SN<+6#{uwh;`!qr?9v;`#520l%$v zn4YMpxHpo>uH=-u6QlIBrm5*tBlxq4JDY~q=SAk3v$>87JPpKOshS$t^H$YT|8#N))z_9k?Uk*p|Eq&TEI@aDVXh%d zH~X~I(vpr)ZdH3SEbT#1rq;3i=k1e1mi#U}Ng?3~Zf_h5@Oo-W3+ zfXydU*ms&%)%dxQRE!cbMp)cYG?;HKvoM9QG*wOpYBBD}@r~0gMaU7>Ez*xcr{zo+ z$vv4g+o@-GZvdZKw-LKCx?daWhqkXc#iDcd`#f0BFu7$1FP^7MbNa~Tp9F{FZgGQV zx(f6_wIG=XG>|#2!mzr$J8M2J4|6Sqvd6ySV(Npk;5FTxM)T31fO|}qPDprp z$gV%USqosFUBhy^ZiUSbzTOX?EW> zI||Pa#jYkt zJmm|C>6GLGHciAgN(?sQ=P|o+^ z>l*0`>M3U}{HJ`x4Bs})brMz*O>Di5jRiIaX!G3JK0xCx9e}*oAzyOglQX~=wwTp; zr-k%P!Rv~8=b@gyxs{Zas(gV5Hh+V)h!UPFtNb`-fs$vD%|No%R~4StM4 zrHoDc9Rao_+B{+GPJRIU??~@8c#|bx)CbFrysD1hd94z;n*vOR^116BQv&*Q#!7g| zQ*kGCK%3l^v6$?ASy{2yH zO7)CS^*Uj3bC~Z_>l<#QI`o;ajPfEjXJiyLE3)Ko0;}>CJBLc5$mWEu^P0mh)C665 zTMp&A%FYVCd!eYS6?+MaO?dFQr-4;rc>;-Rda9zjCLs4jK^)W>f(uS)0=U^LRiIEp?J8cp? z(9v~!uc~D0n`t>wLd<=z0hU{D zo^CeM3^~KCL%un8e*B!f4|uWD^kOX4WdSZ&nK<1bM)`bp`;#!+ve7+afleA68QluT zz-_iG$(*?<`u5?uE*lfcR&S&Hwb47+%A+N$eMuSAc$>t2)!Ou--dk7Cs({RZ!2>!= z>jfJ^BhXg`E^_5)^Iwt+Ssv-8h*Uz zksj~MtC^*(;9Icg?g1@le5Cc)y&9$>#g2awe)_9`(^3aVSz^cWMI5NZFWmNF(K%xv@=Nffk_$$Y}_jDiB$1TElf%i~^ z;l&HFoWkGzbj`ki0A69Z5~Pj70Tk^Q>!JC`cw0MU#C#u-iPj}l1|iis9& zF(*KZlzKhq?uh8V$53r8UUt1AUp>{BDAAR-I_N^;tPKf(-Ty-j<>U?i*m)n0Uf(6*;V7jm*Qn_LWy7mcJfnM1oPus80_nU{NC0w#gp zV7d7QEjOFD++dnyZrO|;iv+qd=gs{+LEa>IAH&iSWG*$~) zI?V6evAN0iHfs=%Mt@DiAQbKEop9ngi4nqZv@mS9?wVhUvn0)=571~l5 z{z{;5U;*2bEh|1Pmi}$@~7Y*p$Qs5<^g=tEJg&onCFAdY50j*?t9=rqEDZ$4*%*>RPe{a zcCOXQJDE@qy=HQvX9E~Ys^|-v&R$$LhRPr&O1vqZ_ivXlvQko?YmCs_U_+io>fnPJ zp6$kyqOW@pASM5peao)t2;levUioby911-PwXx(gJ9^p_BA}r6)lnMkuWNpa3?Asb z0W@03juULk88FCvo}U9IQyGKZ5iX_I-t$L?O=oS?lh`)^;B9~LR&9l2a(vswBlLRd zVrZ5BEPPG(2JrK#%I^Ra>D$(>Tq5m=gRAu;a(Ks4F?bv829O$aONj~b)$ZcL5WX0u ze9Bu#`U@%NUl5Kr{ov--keMd{8}VOVm0lmnFnN;AhJoD;;m;HVe&_yTadINChXoBcbYdopak-`0N^xqjc&2*PvfDsN{37rwG-TlpDYfMB~@8 zQHOCg{dUVf`jy3Rn7J9wZ;k!EDPPSfMd z@r0R;2kxejcphPmYG^Id28HPdyO>T^E~gN(HRn);jl#DXY&U?{5Nq3N7>RG{@Q2av zb5}*iZjz`KTan)5Z!sNP;*?JyLn~v>f~#dgf~tS47b30XsWnCY$S*wv^;X$@QA00$lc|81HZj~c@O!8 z=@TxQr;6sKA9qTMj35&{SxtOf<)pD{1VNc;^f*%Vjg08p!+UJo#y;4bPg?*HRpRuA z9ns_74=2)xViz}dIM}mlxvPxb@06;gxRGscQwdfoV#-u|ec6mvd&(uYop=~}1Mt#f z%-gKxU3U8H%;&SJsx5z7Ws{Yvpw9nhv|@7OiFAtEM!___+F78@R|El4!@{J=5bIKc zDd(IOahHYn30`J6_mO~Zot+C?SoRXAnjF7Hz~zdu2;02vffZ~gCF67h9~Q%ck-|mp z01V8VZ$+KgfB71?XzPYocWpROcaVl%!;`3a5O7*De;&g_4Ku%{`aaw2dqw^CS8&J(_$D_Dr>?%$s~|M zjbYwGO}Ma)8^Hc2y*Y_u2`9={r?NnmGcH2<-A=%(Y8I0t+l-K7Hw^FtkWJ~-w9bq~ z=0>Wq^(W3Q?tT;dfPyeIq#}Y>MIZqny->>oRkJcbdJ99d4x0kHdzH(lBpI92 zioPwdulo%h(gKZ9BdL547YZy2``Htb+GNGxM zVO6U*I}8(Di#_Q59@G8cFv)2yl-yvXvQF@okfc0YD>lloS60ah;|K{Qb7;eAM4T43 zSk$4!Ln>9aE;Zs(fr}5n_d!=cXc)`n?&&6@b$bz^bV~#ml4t=gCUSO%!=iAx zCR3*S_uDRxZN*4h^lQIdQ6ESLF$e;=7aLcVLD0LQ(u}35+9!zCnCPy^~m z4<#sM<3b92Cy~VOpR1jXi#@D*XKeFhbIW_W$ApOs)tXDK2_{^Q;VvY04%M3eF+8pY z6yv2x>YiV!B64=0M%N%R0h$b{&f`LUkVULY{374YyTD;@VI|yo^F_2gQ)rM@Ov#Hi ziZrBibP@9gQ_En>g65K0d1E_FN#jQPkN5MYy*s;juBESel*qgCVXSU^N2{i)?k15h zWT0y5+b(tbK-HSqkr!>Dy$ttkQeI7eS_1NM!@Tjy3NqEUM_omfh^o-Cp4?6sMJ&ObgH&pj>Vt*#i&=ITLm%zhzeN8Kx)SQf~eMaXN z9x&XG#q*!wwB5itO%#of^&nHbyso@y3;PZ?0XxB~MG00x7%)JPA%9~yJKXm~E;w8W z@vJJ;b4RUaU}QH4u=c}e-ninv^^%ii5OvL0*@Y*G3mdAG)XJ9nDhm4mC3yK*X%!4S z&}w)#re_e4>HkSXm`^*S@Va&c@$S{_Se6HO$-TO2yX|T;^eHJ0b{lU1=Z}Jzo2H9_ zYpWda&2XqLc%b(dnpk3hYHRNX;PdZ8t2qC^1$x9ieeZ`nJz2_T7zv#eI7ver(&D)m+fr@tA0DPXQm_x+ zx&e$A#||EACr$S)YD*1%UmQ!I@#4R&kTN>2l--6dVexEAx`$`}bu1?FGjmymx-)z< z0Nrr9kp72DNT`2eeqy={ZL5j36LqYP_eOL|B~qxAjeDYm*PRQttCQ-WXR{Q|uKvqD zoC8m>bs+n#(dW8emb;pqWO1_3O=|ryUU)i*Q>+jU>$@Asim>5S#mUpS;Ou{(Y0nPw zO$w zJf7Btn4zk>`%~I7{80ftNBW;bmH=V1>&O^EGozJ6klM1a{uTC&Ch^n5CA04@o=B`q zvDc-uM;aSDa=ff1erI$&*q#3r390VT;ud6sW`8F^!UC34602rF6Gc)VbuRhUj3xwG z{RU8`IS;BHagpyVYHM`sRy-6x$IkcQsE)ZC(~{( z!3dEowH%!6vJ{PXvUanLmZ@L%ktUTpr5QvMB`i&|95n26d9>hQZE1Vdt-KH>pnUIy z9-~LyyuX!^A_;2{nW;F`O))@GU*Owr`)0pz!0aUS<&KULc^c|aoJdHBGBQ(%zYU90 z`Tk1r&K?Z5d!nDNefn_;HvR5($dR^z`g@UYpI|a3#;`ti<01#RRXh1=Z#%EvoSDND~*Z~Lu)^IK1`oDDIs zyccJCJu8zt{0pXpe@6cQuR%GNZvYYM)F*RF*Qm_J&K+`4z73oU*UVUouq>pFZD!yf zkQu#Vh06bN+qP^%a9o4dn|=}x|K|X;8tb@n*9CvQ0emk0i--Bta!_~UkM-5z0?Tf{ zi80|{tnvOfDAgW9vqZFcoM<^{B(1cE1HO%cj6(DVVoc^b!20^4X)hf?pc61= zMX`|qT^*tYc^Ew4u6_90-koCg%VX_s=M}}NKq&%cv;VDuJbqkSrtHNYS?4TIZNv;| zL_IBA>*^07^UP9Pkku;-zWW2xt?3J7ZcZ%5MOnp^lu};UF zk^Tty+=+HL2Z^d$QW@c$#hB%0Pj#Q*%M;p}Q3+V_)!RM6|Ih?z%oKlN#jiqmv z#cLk1(>uuFm0k%zZp399z;c6OL}^e&p#p|k{jkfr~GGC z4xCB7GB{smu4qxCuTygFCOILhUu6oF4W0aFn})_w<0yw2>2L`8V3nf7nNZAFFJGiQ z&9qtK!>`B|{Z^h0Zp!szOJlYSvu+Pq=!~!kH`)L;dRF7H2^}9Rcb=1)R@T=$wi6)@ z#XglFMNvC({Sy3DvrN0qflTS$u*_)y>I}1u*^;*qMoZO%9oz11iO+P;qmj5zig!9O zO_IKc;K=2pqv7T0={;l(U4{tRekpYZ51EI4PrYs@0S=C^LhAb11&i5C{5_?; zrWyQ9r0GJZwe2mC<=Y?H8sAzgI=GW13oLfXOokO71Ri&&M2}}q0GH+WC&q8>M@ilO z+6j)5J(`+oXIE&)rxe|fgE-9&AsTh1L{@RG{^O<pk^^6?EiTbm%wm2;h zHu>BJyzKBnj8j?449I>IA-*pTyy_E5!%A!_&wIYTB)}R=-MrE-TT(&-Hw_obPb3f8##9oV2Gq zIaylUu=odyzd0EeoL>z* z+tyqukC~{)&oT;j9-!WVI3^g>fwLvp8YayoB`o#U zRNMg6x6_uQJg(M}(<{axn1&czIj~)A#DE7$u(7d`+3Tgrg#P^lE_bKa_NTIZ2NmY< zIdj7JTx%%Idge13A1H}5O1q^nY1xEIXzatNk?*$&&9cU=9(aTql06X*siCcQO3EiB zzuQp;U1=fp0%a3;GKaguW>{2=u_~-jt{nAxhyOlO2b^oPX_^Q;2Zk??NflE0Q)SV; z=u05b1fRC0o~0r#GU2ZV-~%^+w`2O`a9yuH3>M(;IYZZF=GSXK7Gi60t(9uhrOa;t zuXSz!9yfr!1Yi~G4WRx8aMnjGv1570!&Gzw*a-&i0k4l_enXwHE?O+M>PMLR6Axmt z0&#Q$nCH<)hvd!-X532YCmQNsxm*oSJFSHO1%tN^p%utO%oSw2)8v+_%kB#s+139~ zLH?}TkTcbIs?*b;fuHojKkM-eJ`0uGzrSG#|E(5MgPwmMamYc0Ut;vizcw?ae%vq3 z{Ubu$KP8|4xn>iE2%84dKdNeUIJ{K(!N23qf3v~=q0LsHls`=?y{(O|+H-i?Mcqqg z{wJwaQg80w8e`*j*MNz8`V_FyJ98??U)(~YAHDIp%iFImH=867FRfbp>efICGy3ZZ zk$?ST7K>m+Uwwk=UgpegN=ubNJra1ax|1UAA?J>c`<|=mhq-6i2p%y#k~L*{Kf#KF zzW8I_U@T5z%((v6l$$m8q2tbxeu}$DaVQp}IoH0r3iJF-%ZB|$jm6<``TINPTVZT* zusSQ@-raE#);YnJiZrko1~Ut|VfppnV@Mlet+X+0)Ah>E(&B`@aA0*5U?nlxmwAmO zPBBJUlQ(N2P5QE8n9;|6QjTo9nnWy7%3A;2u?2DeoTC^k6^3aG<-Rke6;h`5ej1$s zseMSF-`5!=s<|u2E4tWEM`7}?*^<&HZ(tRSF*sN+oTWc+?O;f%$s+&3he#9dx6E|! zWJjDrkuV!A(uut>K~PVR^eXmLu$gz*s*!BObfVIl?cp-W^F+|iW(JMU{t6Y~z@ue| z8s=A+2xsFPUY%Qo5y##$NdzZX(9=|l7d*!m_zk8P#tXQ$XTRA~Qr0M2*B!k>T*jo`WTWP+k2S6Y8 z7Pw@2*FH|ZcX#vAD;1}g%!>6mx_lS1S2)<)<>O_z$`KUiH=`K&isKFGUV;N$Y@Sc=5VAf^5APT4^p>^F1H0Nge+>K9QK@j`aKCLquA#y zRVy*-F`j7$2M_CV{AstMkKd^!E0f3o-5F4}dY0l@S`i|g9$MCqZKG(Kq$FL-aF+tj z1dWrOgT_WHvDKdY2$t@AQ0cZ0c_f1c{!Tx#x<6iq znyD}UYKx5hj6BY<^p%#d_hk^EBLiYn4=k9S!mMVy=k22rToBixcSpkRD;dPt8vE=6 z1iy@__Dc-o96B5M+bl1n<}|Dylc7A{Z#^_yIHGaq25@|@P^ijzRBO=AmmNH8bnDTX z=Dqz~hA4Wck(85}DYWtOk)}vjyt8I*H1Qewip(#mJglTWb?Rt0q?SdkD;Vy3nE7i8 zD`~z?6QV@063e@;VZ=Vt9)06zC`JnHL7Dz zjY(j|+AOL1pIDWF==;LOyoTbWtUNfu_V3hxO@A-!{QtPHrqTtf#0@}y`Bu=X1>;q% zOb;wz_h>wmz}`6*zr%~A|6OJHUlaJPBj4edJ9Y#3Txg(RI71yHkU^-y%op?K*jU?EFbHxLEy&ThJ$1P5fS5l}~KFAXsoXlB#f(!XtO^hZ5+X)lX^BOtnljQ&4LUJXF zR`8{B&d4>A?*>pP&P6WvK^dK2${Kd=q*Dh0C3*>2K71KtB({Ho+@Mi0!cqFce|TJ{ zzDmPBNDgHm6`-0?YNe}zh@;I(x28vJ*K*$!4YhN({stYfCiC3XHEI85PTq3|35BX! z@Q$~j5X*}ZsZn0iM~H#SDD}|&R%7G?Uc6x!)X^6yHjjvnfwe6D8>uVe1QsQ!GW!OF zU{5T5%_H45Rx>5eXaSO?kf4^Pk=^6z@QQiy!ES&sIcXa}J)^Sn8drUE!Q=I7(-fZX zML0x4*t(D>h& zj~9Z?4Q>FIU~{iz#6(lip~I2wkG;N{#cc^K87*`=3ekxHp}A~_eCV^tqiVVPs}*); z6Ka+tS)^Cqs<6cqO|pvUjO#J+h6Dg4f+i(m*OjM=@(z;|F#1mfmP@ za3!>Ey>V<~b?dyvC*ShQTJQv!f}WrPoG(vG(j7{{-{jJ#LZ!z~B-tMxRZ*rtFF*2O z-fVq!u;%}^N4vO$YE0KXGlT|5a_zl=mz}4Jb!z!cAI@&0o}bf&+S`i|ghQ+nzuyE>U@sU zM^B?>m1wC7hVgN?R7A>U^Gddx(Flk-RdzPSDVM9Z(l#$~1EQonP%rgno*)=l@8H7M zF2-bD)tZOK%c0u7Y6ouBl!y-qD==D`SW0v{cG!2k9rie~iF`Z3^0+6oV@(WEKZx$- z!Fn$T7!oZ+9kKckjo9=m$&}x!!BpDMxn)I8qrG2-p(s{ z7qo&tLC|FJ`2ySkp0!Wqyb%1s)M>J(hYe14!KN-{PC^Duipv9=ypIJ7kRHAkv~XNQ zB&yjjC$^{%GB5ruv%0>vmS$G3k59-W3`Cu*m4>seee2NRyJ)03^*rctz^_G%?I3?i88Oo!_6e8pBr182~!X>e_yT9x7HL&UM5Z?6OQr2*FkooV`|@> z>}*r5Zm6y8fR&hi=8&NGE4vs(S6k5MRuqlE>4Sy%M`7)2k)!vw)VH;v-n_~k5A7b(rNm?Fz}gG1(+dW??(o*ssH_%1QNG(= z-CHA+Fo}F+(efqq<0AkPl~LtNyqVrees!I@YUdhn0Napau^WKe@bNw8M9UJk z;a-`K>Q!A57ZqUvyx4F(&^a0jy(^ZB;Im9u$ERVr4NmrR`k+jDVy^b^vlt5Rchxzh zCY&FG%R(sp*xJ1u#3_qlZ??$d{C3QemmXLakWTE~uiHm&BFT;&quH0PG#)M~qT`YX zuY9hPw72DxN!UiZ%D`pnXiTC|<$5j3EVpNyJG(Zk$nYK6E}}|&ca^tvP*Gdw?6f^IV>`Tbaid{YGbEIed8$6DYz$2&Y%4nVu%Bq)z$}Dj;n^qxu)@WH?A_0l2Emm z%yv2CY+d?|8j#dQX&$-hdGvR#JH__T7!&qdCA3vuDv-TMMJa=|JpNocjOO}^bJ7S) z^JP>0?Z9Zx@AO&bs^SP|z9$>tN~V~VFdGw=Txc1`$*N3UVTI>I_#pP8{E5t#P9w=3 zQR>#Hvg^t6d#S3ufFdMMS2jd1RPC8T@biOSwN(Rx9u4RD4!nfjNMs$b%yTl5BSXO>WHCl~H}l=*8q z)hSjZ)ASvbQQ%d10~p}E7;OY!a->2Ly01GH5`HBdt@4lI#{Ql2Z$F-b=o3t5SD4Nk zN>!=5xc%Y3rsg!4D^xdt_qIWPxwONAr{O8m3SM_ouM;xhmN$SDm69|{gr~F)jyFm|9xpG_W|Pwa4V^KF}=iI0kfq}M{WQj9lx>a_#e>T z0ma?`4r#1YPhhy$7&W(~Zq0KclQT38WD?{g^J4Xfk61pxav&&Ba|mW0k|L~G@%#Hm zvM~tUcSAgd1zg)3USrhnCKdIZX@{q$;pS|udFhg}izsn_MEATkzbve(&UD>^oX-x~if3aF-Gk(8#XHIC!i{ybo(wpA$L1^^mLp=x zZ%srJc2^t7B@A#V*wlJ*m))+!%(A~4V43_7Y1DZca7#0kI5RIvk)a(+9+LLeOMOo(}>@&}(M z`d&XgJx;@}!)7Ptu@05quq#p9F(a&k7(JQnUuy2ieZE1c0KV^h-`IW1dF8_7b?sGn z%bSFw9{s1Moi!D8DcDPEhs!K=TS2HN-{TpG)$SRStF$EL9itzlVc!5yW))qQggqEz z=5(ILv&zjpCtI_9m~!vAz7)Oc8`&)C@pyu8f?)a=otutDxhT}HnB@!Wg1bT{)Vg>A zLJv8OZ*3KoAEx92F76G$w2h}M|C8)P)#ts2Axn)yns8e~N^Q2Y0gvl2g11XfieHZH z4C*J6VVlHN4)v~aPT!*Jw}mSY0=xP4V`&$x+^g})n*R*7+o9(m|d5}-KpaOA{GcZv=2m_DfA zBzD*Aj-Z&Kg7fi3VgJ>IE~Z4cPiD83Y4w@j%(PTm@#6}E3fiKH_G|r9%adP`M z(SeqR*e?2Fs@&MSnD<4RBw!HdSg6GJXqRx7-fH+PclGUC)KR9V0XdmXsD(K zYO7^`*2cM(Ae-s8;u^+!VFmIVU_^%UAWfdTPODcQD6aGuQ*78qDxI!7DU)e9 z20gBlrC&?* zuo7vlQcLT5qVP+egqW*)Je*w=c=SOS^(77?lP2Ts(L}e_;dzdA57VQn%2XLKmPQ&oC1u z$Y_yeqP{IjkJ-e%2=5Pm5v5ffz542__nlh|PRj0PBuj%QUMg&v zHMNy^Me?-h>R2xf(Mz8LR`NVoIdx^w-vD6P=3v5BO+JK21ReI(d+)nT#ei2Tx||zPV!rG}^!kzg z4-yG{V()>>sFX+cTHQ*dbz5$ev4cxL6ZnI21wRI6v{G+%Eq^TCnJa(0Lm3P`G zah=lix%;nb5N`bsES^uBx?PQi^L9hn^O441RNL-1ZU zxqm*P{s+Z_;=~iJS&>^Ap>P`wSLm72if&U3bqv*XC$M7Th!pgre5N(n8KF^lp>mOY+50NS_dXSP5q0I(F|ni%W3`u6$rzZI27QC>(q<%AF1g}7 zo&zleN`FhD5>iHSR#CdU?e{GzGr!}GH>s4cC7pl(<%YfvNnyUKFkTSAlrT5L;>em< ziNH|?OXXpdWtM>UCl>|??f$HPMpQ?JHH(J}KJg(HGF}AkZj=WPQm@JjSVu-m^~PLG zOk_}bjFAV5(I7HY?kA)4porXbI^XAIbweis)5+J2o!s5t5kI1)j}^F! zPM`WxmtR*boPrzE@O}$#E3z`g{=8SA@6THq(zmfh{%W&=wfvtpGx&X>`HO{r

U*85UL*BK_^eIq8J{8jv% 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 M1`-ld)l~!i53HvLI{*Lx From 3b35d6e632d85ae2ea152b978c9f2ec599d1e19a Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 11 Jul 2026 15:28:51 +0300 Subject: [PATCH 12/12] Clarify unclear parts of the report --- Danil_Grezin/Danil_Grezin_report.tex | 42 ++++++++++++++++------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Danil_Grezin/Danil_Grezin_report.tex b/Danil_Grezin/Danil_Grezin_report.tex index d35a552..2414037 100644 --- a/Danil_Grezin/Danil_Grezin_report.tex +++ b/Danil_Grezin/Danil_Grezin_report.tex @@ -44,42 +44,48 @@ \section{Постановка задачи} -Умножение плотных матриц с элементами одинарной точности (стандартный 32-битный формат представления чисел с плавающей точкой) является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от эффективности ее реализации на графических процессорах. +Умножение плотных матриц с элементами одинарной точности (стандартный 32-битный формат представления чисел с плавающей точкой) является одной из наиболее важных вычислительных операций в высокопроизводительных вычислениях, поэтому производительность многих приложений напрямую зависит от производительности реализации данной операции на графических процессорах. -Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием технологии OpenCL на основе существующего набора реализаций умножения матриц. Реализации отличаются применяемыми методами повышения производительности, направленными на сокращение числа обращений к памяти, более эффективное использование локальной памяти и регистров, а также увеличение объема вычислений, выполняемых каждым потоком. Для ряда реализаций предусмотрены настраиваемые параметры, включая размеры вычислительных блоков, объем работы, выполняемой одним потоком, и ширину используемых векторов, значения которых могут существенно влиять на достигаемую производительность. +Работа выполнялась в рамках учебного исследования методов оптимизации вычислений на графическом процессоре NVIDIA GeForce RTX 4060 с использованием OpenCL (Open Computing Language)\footnote{The Khronos Group. Обзор OpenCL. URL: \url{https://www.khronos.org/opencl/} (дата обращения: 08.03.2026).}~--- стандарта разработки программ для выполнения параллельных вычислений. Исследование проводилось на основе существующего набора реализаций умножения матриц. Реализации отличаются применяемыми методами повышения производительности, направленными на сокращение числа обращений к памяти, повышение эффективности использования локальной памяти и регистров, а также изменение распределения вычислений между потоками. -\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения матриц на производительность вычислений при их выполнении на графическом процессоре, а также автоматизация подбора параметров оптимизации и определение наиболее эффективной конфигурации для используемого графического процессора. +\textbf{Целью работы является} экспериментальное исследование влияния различных методов оптимизации умножения плотных матриц на производительность вычислений при их выполнении на графическом процессоре. -Результаты работы позволяют оценить эффективность отдельных оптимизаций и их вклад в итоговую производительность вычислений. Полученные данные могут использоваться для выбора оптимальных параметров реализации умножения матриц на конкретном графическом процессоре. +Результаты работы позволяют оценить влияние отдельных оптимизаций на производительность вычислений. Полученные данные могут использоваться для выбора параметров реализации умножения матриц, оптимальных по критерию максимального среднего значения производительности на конкретном графическом процессоре. Для достижения поставленной цели были решены следующие задачи: \begin{itemize} \item провести экспериментальное исследование производительности различных реализаций умножения матриц, представленных в проекте myGEMM\footnote{Cedric Nugteren. Репозиторий проекта myGEMM. URL: \url{https://github.com/CNugteren/myGEMM} (дата обращения: 10.03.2026).}; \item проанализировать влияние отдельных методов оптимизации, используемых в реализациях умножения матриц, на производительность выполнения вычислений на графическом процессоре; \item автоматизировать подбор параметров оптимизации; -\item определить оптимальные значения параметров для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте myGEMM по умолчанию. +\item определить значения параметров, обеспечивающие максимальное среднее значение производительности для используемого графического процессора и сравнить их со значениями, предлагаемыми в проекте myGEMM по умолчанию. \end{itemize} \section{Описание предлагаемого решения} В качестве основы для выполнения работы был использован проект myGEMM, реализующий набор методов оптимизации умножения матриц с использованием OpenCL. -В проекте myGEMM представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность вычислений на графическом процессоре и делает проект myGEMM удобной платформой для экспериментального исследования подходов к повышению эффективности вычислений. +В проекте myGEMM представлено 11 вариантов вычислительных ядер, каждое из которых реализует новый метод оптимизации умножения матриц. Наличие нескольких реализаций позволяет проследить влияние методов оптимизации на производительность вычислений на графическом процессоре и делает проект myGEMM удобной платформой для их экспериментального исследования. -В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор оптимальных параметров. Все программы расположены в корневом каталоге проекта, разрабатываемого в рамках данной работы: +Для отдельных реализаций предусмотрены настраиваемые параметры, влияющие на организацию вычислений. При умножении матриц вычисляемая область результирующей матрицы разбивается на вычислительные блоки, каждый из которых обрабатывается группой потоков. Размер такого блока задается параметром TS (Tile Size). Параметр WPT (Work Per Thread) определяет, сколько элементов результирующей матрицы вычисляет один поток, позволяя изменять соотношение между количеством потоков и объемом работы каждого из них. Параметр WIDTH определяет количество элементов, обрабатываемых одной векторной операцией. Для более детальной настройки отдельных реализаций используются параметры TSM, TSN и TSK, задающие размеры обрабатываемых блоков по измерениям M, N и K соответственно, где M и N соответствуют размерам строк и столбцов результирующей матрицы, а K~--- размеру внутреннего измерения, по которому выполняется суммирование при умножении матриц. Параметры WPTM и WPTN определяют количество элементов результирующей матрицы, вычисляемых одним потоком, по измерениям M и N соответственно. Изменение данных параметров может существенно влиять на достигаемую производительность. + +В рамках работы были разработаны программы на языке Python, обеспечивающие автоматический запуск вычислительных ядер, сбор результатов измерений, их статистическую обработку и подбор параметров, обеспечивающих максимальное среднее значение производительности. + +Работа программ организована следующим образом. На этапе настройки формируется набор параметров для запуска вычислительных ядер. При автоматическом подборе производится перебор допустимых комбинаций параметров с проверкой ограничений, связанных с особенностями графического процессора и конкретной реализацией ядра. Для каждой конфигурации выполняется сборка проекта с выбранными параметрами, после чего производится серия запусков программы и извлечение полученных значений производительности из ее вывода. Полученные результаты сохраняются и используются для последующей статистической обработки. На основе результатов измерений вычисляются статистические характеристики и выбирается конфигурация, обеспечивающая максимальное среднее значение производительности. Все программы расположены в корневом каталоге проекта, разработанного в рамках данной работы: \begin{itemize} \item \texttt{run\_experiments\_default.py}~--- запуск измерений с параметрами по умолчанию для каждого ядра; \item \texttt{run\_experiments\_tuned.py}~--- перебор всех допустимых комбинаций параметров для каждого ядра с проверкой ограничений (объем памяти, делимость значений); -\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\% доверительного интервала, проверка нормальности; +\item \texttt{calculate\_results\_default.py}~--- статистическая обработка результатов по умолчанию: расчет среднего, стандартного отклонения, 95\%-го доверительного интервала, проверка нормальности распределения; \item \texttt{calculate\_results\_tuned.py}~--- статистическая обработка результатов с перебором параметров и выбор лучшей конфигурации по наибольшему среднему значению производительности. \end{itemize} -Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. +Для проверки корректности разработанных программ были написаны модульные тесты с использованием \texttt{pytest}\footnote{pytest development team. Документация pytest. URL: \url{https://docs.pytest.org/en/stable/} (дата обращения: 20.04.2026).}, размещенные в директории \texttt{tests/unit/}. Тесты охватывают корректность функций проверки подбираемых параметров, статистической обработки результатов и обработки выбросов. \section{Экспериментальное исследование производительности} -С использованием разработанных программ были проведены измерения производительности ядер myGEMM в стандартной и оптимизированной конфигурациях. +С использованием разработанных программ были проведены измерения производительности всех ядер проекта myGEMM. Для каждого ядра выполнялось измерение стандартной конфигурации, использующей параметры, заданные в исходном проекте myGEMM. Для ядер, поддерживающих настройку параметров, дополнительно проводилось сравнение с оптимизированной конфигурацией, полученной в результате автоматического подбора параметров по критерию максимального среднего значения производительности. Для ядер, не имеющих настраиваемых параметров, исследование ограничивалось измерением стандартной конфигурации. + +Целью экспериментального исследования является оценка влияния методов оптимизации и автоматического подбора параметров вычислительных ядер на производительность умножения плотных матриц при выполнении вычислений на графическом процессоре. Эксперименты проводились на следующей конфигурации вычислительной системы: \begin{itemize} @@ -95,7 +101,7 @@ \section{Экспериментальное исследование произ \item флаги компиляции \texttt{-O3 -arch=sm\_89 -Xcompiler -Wall}. \end{itemize} -Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размера \(8192 \times 8192\) (степень двойки) и \(8320 \times 8320\) (не степень двойки, для проверки ядер с поддержкой матриц, размеры которых не кратны размеру вычислительного блока). По результатам измерений вычислялись среднее значение производительности (GFLOPS), стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро-Уилка. +Для каждой конфигурации выполнялось 40 измерений производительности после серии предварительных запусков. Между компиляциями и сменами размеров матриц делалась пауза для стабилизации температурного режима графического процессора. В качестве исследуемой задачи использовалось умножение квадратных матриц размеров \(8192 \times 8192\) и \(8320 \times 8320\). Размер 8192 выбран как достаточно большое значение, являющееся степенью двойки и позволяющее исследовать производительность вычислительных ядер при больших объемах вычислений. Размер 8320 выбран как близкое по величине значение, не являющееся степенью двойки, для проверки ядер, поддерживающих обработку матриц произвольного размера. По результатам измерений вычислялись среднее значение производительности, стандартное отклонение и 95\%-й доверительный интервал, а также выполнялась проверка нормальности распределения результатов с использованием тестов Д'Агостино и Шапиро-Уилка. Время выполнения каждого измерения определялось с использованием функции \texttt{gettimeofday}, обеспечивающей получение времени в секундах. Каждый элемент результирующей матрицы при умножении плотных квадратных матриц размера \(N \times N\) вычисляется как скалярное произведение строки и столбца длины \(N\), что требует выполнения \(N\) операций умножения и \(N\) операций сложения. Таким образом, для вычисления одного элемента выполняется \(2N\) арифметических операций, а для всей результирующей матрицы, содержащей \(N^2\) элементов,~--- \(2N^3\) операций. Производительность измеряется в GFLOPS (Giga Floating-point Operations Per Second) как число арифметических операций с числами с плавающей точкой в секунду, где 1 GFLOPS соответствует $10^9$ операциям в секунду. Итоговая производительность вычислялась по формуле: \[ @@ -103,13 +109,13 @@ \section{Экспериментальное исследование произ \] где \(t\)~--- время выполнения одного измерения в секундах. -Результаты измерений для базовой конфигурации, а также после автоматического подбора параметров представлены на странице репозитория в файле \texttt{README.md}. +Результаты измерений для стандартной конфигурации, а также после автоматического подбора параметров, обеспечивающих максимальное среднее значение производительности, представлены на странице репозитория в файле \texttt{README.md}. -Сравнение производительности ядер до и после подбора параметров для матриц приведено на рисунке~\ref{fig:kernel-comparison}. Бордовым и малиновым цветами показаны результаты выполнения через CUDA и OpenCL соответственно, а белыми отрезками обозначено стандартное отклонение результатов измерений. В рамках сравнения рассматриваются 2 набора параметров: <> (параметры, заданные в исходном проекте myGEMM) и <> (оптимальные параметры, полученные в результате автоматического подбора). +Сравнение производительности ядер до и после подбора параметров для исследуемых размеров матриц приведено на рисунке~\ref{fig:kernel-comparison}. На горизонтальной оси графика представлено среднее значение производительности в GFLOPS, вычисленное по результатам серии измерений, а на вертикальной оси~--- названия вычислительных ядер проекта myGEMM с указанием размера матриц и используемой конфигурации параметров. Вариант <> соответствует параметрам, заданным в исходном проекте myGEMM. Вариант <> соответствует конфигурации, полученной в результате автоматического подбора допустимых комбинаций параметров ядра и обеспечивающей максимальное среднее значение производительности среди рассмотренных вариантов. Для некоторых ядер на графике представлен только вариант <>. Это связано либо с отсутствием настраиваемых параметров, допускающих автоматический подбор конфигурации, либо с тем, что подбор параметров не привел к увеличению среднего значения производительности. Бордовым цветом показаны результаты выполнения с использованием CUDA (Compute Unified Device Architecture)\footnote{NVIDIA. CUDA Toolkit Documentation. URL: \url{https://docs.nvidia.com/cuda/} (дата обращения: 10.03.2026).}~--- платформы для разработки программ, выполняющих параллельные вычисления на графических процессорах. Малиновым цветом показаны результаты выполнения с использованием OpenCL. Белыми отрезками обозначено стандартное отклонение результатов измерений. \begin{figure}[htbp] \centering - \includegraphics[width=0.537\textwidth]{kernel_comparison.pdf} + \includegraphics[width=0.7\textwidth]{kernel_comparison.pdf} \caption{Производительность вычислительных ядер до и после подбора параметров} \label{fig:kernel-comparison} \end{figure} @@ -122,7 +128,7 @@ \section{Экспериментальное исследование произ \item ядро 7~--- прирост производительности около 29\% за счет уменьшения ширины вектора (WIDTH с 4 до 2). \end{itemize} -Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности, их параметры по умолчанию уже являлись оптимальными или почти оптимальными для используемой видеокарты. +Остальные ядра (1, 2, 3, 4, 8, 9, 10, 11) не показали заметного изменения производительности. Их параметры, заданные в исходном проекте myGEMM, уже обеспечивали максимальное или близкое к максимальному среднее значение производительности для используемой видеокарты среди рассмотренных конфигураций. Полученные результаты подтверждают, что учет особенностей конкретного графического процессора при подборе параметров вычислительных ядер позволяет в ряде случаев существенно повысить производительность без изменения алгоритма вычислений. @@ -133,13 +139,13 @@ \section{Заключение} \begin{itemize} \item разработаны программы для автоматизированного запуска измерений (\texttt{run\_experiments\_default.py}, \texttt{run\_experiments\_tuned.py}) и статистической обработки результатов (\texttt{calculate\_results\_default.py}, \texttt{calculate\_results\_tuned.py}); \item написаны модульные тесты для проверки корректности скриптов (\texttt{tests/unit/}); - \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); - \item выполнен автоматический перебор параметров и определены оптимальные конфигурации для NVIDIA GeForce RTX 4060. + \item проведены измерения производительности 11 вычислительных ядер в стандартной и оптимизированной (для ядер, поддерживающих настройку параметров) конфигурациях на матрицах размером \(8192 \times 8192\) и \(8320 \times 8320\); + \item выполнен автоматический перебор параметров и определены конфигурации, обеспечивающие максимальное среднее значение производительности для NVIDIA GeForce RTX 4060. \end{itemize} Репозиторий: \url{https://github.com/Snaffys/myGEMM}. Техническая документация, описание методики проведения экспериментов, а также результаты измерений и графики производительности представлены в файле \texttt{README.md} репозитория. -Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер при разработке высокопроизводительных приложений для графических процессоров. Разработанные средства автоматизации позволяют существенно сократить трудоемкость экспериментальных исследований и могут быть использованы при дальнейшем изучении методов оптимизации вычислений на графических процессорах. +Полученные результаты демонстрируют практическую значимость автоматического подбора параметров вычислительных ядер, позволяющего повысить производительность вычислений на графическом процессоре без изменения алгоритма умножения матриц. \end{document}