какие-то правки, но он всё равно ничего не глядел
This commit is contained in:
@@ -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{Сборка и запуск}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user