diff --git a/report/report.tex b/report/report.tex index f1e03b0..c733c45 100755 --- a/report/report.tex +++ b/report/report.tex @@ -256,7 +256,8 @@ Host polytech \item матрица $A$ и вектор $b$ один раз копируются на устройство, а далее итерационный процесс выполняется на GPU; \item завершение итераций контролируется через флаг \texttt{converged}, который может быть сброшен любым потоком, если изменение соответствующей компоненты превысило $\varepsilon$; \item после завершения расчёта на стороне CPU вычисляются невязка и ошибка относительно заранее известного решения; - \item для удобства дальнейшего анализа программа может сохранять результаты в CSV-файл. + \item для удобства дальнейшего анализа программа может сохранять результаты в CSV-файл; + \item конфигурация запуска ядра: размер блока фиксирован и равен $256$ потокам, размер сетки вычисляется как $\lceil n / 256 \rceil$, то есть всего активно ровно $n$ потоков --- по одному на строку матрицы. Значение $256$ потоков в блоке взято как оптимальное по результатам аналогичного GPU-эксперимента прошлого семестра и задаётся флагом \texttt{--threads 256} в \texttt{task1/scripts/run\_cuda.slurm}. \end{itemize} Такой вариант не является буквальной реализацией классического LU-LINPACK, однако решает ту же прикладную задачу --- измерение производительности при решении плотной СЛАУ --- и позволяет исследовать эффективность распараллеливания на GPU. @@ -446,6 +447,8 @@ Host polytech Для распараллеливания волнового алгоритма с использованием MPI \cite{gropp2014mpi} применена декомпозиция полигона по строкам. Полигон размера $n \times n$ разбивается на горизонтальные полосы, каждая из которых обрабатывается отдельным MPI-процессом. При использовании $P$ процессов каждый из них получает примерно $n / P$ строк. +В экспериментах на СКЦ запускается ровно один MPI-ранг на узел (\texttt{--ntasks-per-node=1}, \texttt{mpirun --map-by ppr:1:node --bind-to none}), поэтому число процессов $P$ совпадает с числом узлов и принимает значения $1$, $2$ или $4$. На каждом ранге выделяется \texttt{--cpus-per-task=56} CPU. + Для корректной обработки граничных ячеек каждый процесс дополнительно хранит по одной теневой строке (ghost row) сверху и снизу, содержащей актуальные значения расстояний из соседних процессов. Алгоритм работы программы: @@ -467,7 +470,7 @@ Host polytech \subsection{CUDA-реализация для сравнения} -Для сопоставления с MPI-реализацией подготовлена CUDA-версия того же волнового алгоритма, основанная на программе прошлого семестра. В отличие от исходной версии, размер полигона задаётся через аргумент командной строки (вместо \texttt{\#define}). Используется ядро с глобальной памятью: каждый поток обрабатывает несколько ячеек с шагом, равным общему числу потоков. Полный текст CUDA-реализации приведён в приложении Ж. +Для сопоставления с MPI-реализацией подготовлена CUDA-версия того же волнового алгоритма, основанная на программе прошлого семестра. В отличие от исходной версии, размер полигона задаётся через аргумент командной строки (вместо \texttt{\#define}). Используется ядро с глобальной памятью. Ядро запускается с конфигурацией \texttt{blocks = 256}, \texttt{threads = 256} (итого $65\,536$ потоков), при этом каждый поток обрабатывает несколько ячеек с шагом, равным общему числу потоков. Значения \texttt{blocks = 256} и \texttt{threads = 256} выбраны как оптимальные по результатам исследования прошлого семестра для той же задачи поиска пути на полигоне и передаются как аргументы командной строки в \texttt{task2/scripts/run\_cuda.slurm}. Полный текст CUDA-реализации приведён в приложении Ж. \subsection{Сборка и запуск}