Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add a document describing the rationale.

  • Loading branch information...
commit 5c30fb5e8854a61c59d15fb23aa12ac1941ef2a3 1 parent c0c999d
@angavrilov authored
Showing with 1,304 additions and 0 deletions.
  1. +1,304 −0 doc/report.ru.lyx
  2. BIN  doc/report.ru.pdf
View
1,304 doc/report.ru.lyx
@@ -0,0 +1,1304 @@
+#LyX 1.6.4 created this file. For more info see http://www.lyx.org/
+\lyxformat 345
+\begin_document
+\begin_header
+\textclass article
+\begin_preamble
+\usepackage[russian]{babel}
+\usepackage[utf8]{inputenc}
+
+\usepackage{lastpage}
+
+\usepackage[pdftex,
+bookmarks=true,
+bookmarksnumbered=true,
+pdfpagemode=None,
+pdfstartview=FitH,
+pdfpagelayout=SinglePage,
+colorlinks=true,
+urlcolor=magenta,
+pdfborder={0 0 0},
+unicode
+]{hyperref}
+
+\usepackage{cmap} % for serchable pdf's
+\end_preamble
+\use_default_options true
+\language russian
+\inputencoding utf8
+\font_roman lmodern
+\font_sans cmss
+\font_typewriter lmtt
+\font_default_family default
+\font_sc false
+\font_osf false
+\font_sf_scale 100
+\font_tt_scale 100
+
+\graphics default
+\paperfontsize default
+\spacing single
+\use_hyperref false
+\papersize a4paper
+\use_geometry false
+\use_amsmath 1
+\use_esint 1
+\cite_engine basic
+\use_bibtopic false
+\paperorientation portrait
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\defskip medskip
+\quotes_language english
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+\tracking_changes false
+\output_changes false
+\author ""
+\author ""
+\end_header
+
+\begin_body
+
+\begin_layout Title
+Генерация кода для SSE/CUDA в задачах атмосферного моделирования
+\end_layout
+
+\begin_layout Author
+А.
+ Н.
+ Гаврилов
+\end_layout
+
+\begin_layout Date
+\begin_inset ERT
+status open
+
+\begin_layout Plain Layout
+
+
+\backslash
+today
+\end_layout
+
+\end_inset
+
+ (Draft)
+\end_layout
+
+\begin_layout Abstract
+Автоматизированная генерация кода из высокоуровневого описания позволяет
+ легко адаптировать программу под существенно различные архитектуры, такие
+ как Intel Core 2 (SSE2) и NVidia CUDA.
+ Для реализации прототипа был использован язык Common Lisp в реализации
+ ECL
+\begin_inset CommandInset citation
+LatexCommand cite
+key "ref-ecl"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Section
+Свойства сеточных моделей
+\end_layout
+
+\begin_layout Standard
+Наиболее часто используемым методом атмосферного моделирования являются
+ сеточные алгоритмы.
+ Они основаны на представлении состояния атмосферы в виде двумерных или
+ трехмерных массивов.
+ Размерности массива соответствуют реальным физическим измерениям с использовани
+ем постоянного шага, либо более сложной, но аналогичным образом фиксированной
+ сетки.
+\end_layout
+
+\begin_layout Standard
+Вычислительная часть модели состоит из набора формул, задающих взаимодействие
+ между величинами.
+ В ходе выполнения каждой итерации алгоритма они вычисляются для всех элементов
+ выходного массива, получая на вход значения из соответствующих участков
+ других массивов.
+ Для крайних значений индексов часто используются специальные варианты формул.
+ Сейчас эти формулы нередко выводятся с помощью систем вроде Maple
+\begin_inset CommandInset citation
+LatexCommand cite
+key "maple"
+
+\end_inset
+
+.
+ Формулы могут содержать условные операторы, например для реализации ступенчатой
+ функции.
+\end_layout
+
+\begin_layout Standard
+Такая схема вычислений сама по себе очень хорошо поддается параллелизации.
+ Однако реальные модели могут содержать следующие осложняющие факторы:
+\end_layout
+
+\begin_layout Itemize
+Итерация может делаться не с единичным шагом, например, обращаться к элементам
+ массива через один.
+ Пропущенные индексы могут быть использованы при вычислении другой формулы,
+ либо полностью игнорироваться.
+\end_layout
+
+\begin_layout Itemize
+Оптимальное расположение размерностей массива в памяти, а также порядок
+ циклов, может быть сложно определить с первого взгляда.
+\end_layout
+
+\begin_layout Itemize
+Некоторые схемы сглаживания используют в формуле результат вычисления соседнего
+ элемента вдоль одной из размерностей.
+\end_layout
+
+\begin_layout Standard
+Хотя сами по себе эти проблемы обойти не сложно, ручная коррекция формул
+ чревата возникновением трудно обнаружимых ошибок.
+\end_layout
+
+\begin_layout Section
+Целевые архитектуры
+\end_layout
+
+\begin_layout Subsection
+Intel Core 2 (SSE2)
+\end_layout
+
+\begin_layout Standard
+Как и большинство современных процессоров общего назначения, Intel Core
+ 2 -- суперскалярная архитектура, способная выполнять в пределе до 4 команд
+ за такт на каждом ядре.
+ Все обращения к памяти идут через два уровня кэширования.
+ На первом уровне каждое ядро имеет 32КБ со скоростью доступа порядка нескольких
+ тактов.
+ Второй уровень объемом до 12МБ используется сообща всеми ядрами.
+\end_layout
+
+\begin_layout Standard
+Крупномасштабный параллелизм на данной архитектуре достигается путем разделения
+ задачи на потоки по числу ядер.
+ Каждый поток может выполнять любые команды, используя общую память для
+ взаимодействия.
+ С целью улучшения эффективности использования кеша, потоки имеет смысл
+ привязывать к конкретным ядрам средствами операционной системы.
+\end_layout
+
+\begin_layout Standard
+На низком уровне дополнительный параллелизм достигается путем использования
+ команд, оперирующих 128-битными регистрами, каждый из которых может содержать
+ 4 вещественных числа.
+ Процессор предоставляет команды для обмена с памятью, арифметики
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+Денормализованные числа замедляют вычисления в разы.
+ Если задача позволяет, их можно отключить через управляющий регистр mxcsr.
+\end_layout
+
+\end_inset
+
+, сравнений и побитных логических операций.
+ Для их использования внутренний цикл разворачивается на 4 итерации; в связи
+ с особенностями команд обмена с памятью для этого необходимо чтобы обращения
+ к массивам шли с шагом 1.
+\end_layout
+
+\begin_layout Standard
+Современные компиляторы способны автоматически использовать команды SSE
+ в простых случаях, однако, как правило, не могут обработать условные операторы,
+ хотя их возможно эмулировать с помощью команд сравнения и логических операций.
+ Это связано с тем, что такая эмуляция требует вычисления обеих ветвей условия,
+ что нарушает гарантии языка C.
+\end_layout
+
+\begin_layout Standard
+Компиляторы также предоставляют возможность прямого использования векторных
+ операций через специальные встроенные
+\begin_inset Quotes eld
+\end_inset
+
+функции
+\begin_inset Quotes erd
+\end_inset
+
+, транслируемые напрямую в соответствующие команды
+\begin_inset CommandInset citation
+LatexCommand cite
+key "msdn-sse"
+
+\end_inset
+
+.
+ Компилятор при этом продолжает отвечать за распределение регистров и взаимодейс
+твие с памятью.
+\end_layout
+
+\begin_layout Subsection
+NVidia CUDA
+\end_layout
+
+\begin_layout Standard
+В отличие от основного процессора, процессоры видеокарт NVidia
+\begin_inset CommandInset citation
+LatexCommand cite
+key "cuda-intro"
+
+\end_inset
+
+ выполняют команды внутри одного потока строго в порядке их появления.
+ Это компенсируется возможностью выполнения многих сотен потоков на одном
+ ядре, с нулевой стоимостью переключения и аппаратным планировщиком.
+\end_layout
+
+\begin_layout Standard
+Также отсутствует обязательное кеширование памяти.
+ Вместо этого каждое ядро содержит 8 или 16 тысяч 32-битных регистров, распредел
+яемых между выполняемыми потоками, а также 16КБ общей памяти для обмена
+ данными между ними
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+При корректном использовании эта память работает с той же скоростью что
+ и регистры, но требует дополнительного копирования данных.
+\end_layout
+
+\end_inset
+
+.
+ Кроме этого, одновременное обращение многих потоков к соседним ячейкам
+ памяти автоматически группируется в один запрос к внешней шине
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+На эту оптимизацию сильно влияет выравнивание данных, особенно в старых
+ моделях видеокарт.
+\end_layout
+
+\end_inset
+
+.
+ Наконец, в процессоре видеокарты есть кеш для доступа к текстурам, но их
+ использование также требует явного изменения кода программы.
+\end_layout
+
+\begin_layout Subsubsection
+Блоки
+\end_layout
+
+\begin_layout Standard
+На верхнем уровне параллелизации, задача разделяется на т.н.
+ блоки, организованные в двумерную сетку.
+ Размер сетки может задаваться во время исполнения, и ограничен только использов
+анием для индексов 16-битных чисел.
+ Размер сетки и координаты текущего блока доступны для использования в коде,
+ исполняемом на видеокарте.
+\end_layout
+
+\begin_layout Standard
+Блоки из сетки автоматически распределяются аппаратным планировщиком по
+ свободным ядрам
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+В зависимости от модели, процессор содержит от 2 до 30 ядер.
+\end_layout
+
+\end_inset
+
+.
+ Каждое ядро может одновременно выполнять несколько блоков; их количество
+ ограничивается потребностью блоков в регистрах и общей памяти, а также
+ ресурсами планировщика
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+Для эффективной работы необходима загрузка минимум 25%, т.е.
+ 4 блока на ядро при 64 потоках на блок.
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Потоки внутри блока могут синхронизироваться с помощью специальной команды,
+ а также обмениваться информацией через участок общей памяти.
+ Сами блоки выполняются в произвольном порядке, и обмениваться информацией
+ не могут.
+\end_layout
+
+\begin_layout Subsubsection
+Потоки
+\end_layout
+
+\begin_layout Standard
+Каждый из блоков содержит одинаковое количество потоков, организованных
+ в двумерную или трехмерную сетку.
+ Общее количество потоков на одном ядре, а значит и в блоке, ограничено
+ числом 512 или 1024
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+В связи с пределом в 8 блоков, 100% загрузка требует минимум 128 потоков
+ в блоке.
+\end_layout
+
+\end_inset
+
+ в зависимости от модели.
+ Аналогично блокам, размер сетки задается во время исполнения, и доступен
+ программе вместе с координатами потока.
+ Все потоки выполяют одну и ту же процедуру, и изначально различаются только
+ значениями своих координат.
+\end_layout
+
+\begin_layout Standard
+Каждый поток получает собственный набор регистров из общего пула.
+ Их распределение делается сразу по группам из 64 потоков.
+ Практический опыт показывает, что для эффективного выполнения следует держать
+ потребность потока в регистрах в пределах 64.
+\end_layout
+
+\begin_layout Standard
+Аппаратный планировщик обрабатывает потоки статическими группами в 32 штуки
+ (
+\begin_inset Quotes eld
+\end_inset
+
+warp
+\begin_inset Quotes erd
+\end_inset
+
+)
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+Для того чтобы скрыть задержки на запись в регистры необходимо наличие минимум
+ 6 активных групп (не обязательно в одном блоке).
+\end_layout
+
+\end_inset
+
+.
+ В оптимальном случае он может одновременно выполнить одну и ту же команду
+ для всех потоков группы
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+Реально ядро содержит только 8 вычислительных элементов и обрабатывает группу
+ за 4 шага.
+ Однако с точки зрения планировщика это атомарная операция.
+\end_layout
+
+\end_inset
+
+.
+ В случае если потоки расходятся из-за выбора различных ветвей в условном
+ операторе, планировщик вынужден выполнить обе ветви по очереди, временно
+ отключая потоки, пошедшие по другой ветви.
+ Это приводит к снижению производительности.
+\end_layout
+
+\begin_layout Standard
+Группы, ожидающие данные из памяти, или момента синхронизации, временно
+ блокируются.
+ Остальные выполняются планировщиком по очереди.
+ Кроме этого, в связи с тем, что для выполнения команды MADD используются
+ специализированные элементы, она может выполняться параллельно с любой
+ другой командой в другой группе.
+\end_layout
+
+\begin_layout Subsubsection
+Процесс разработки и исполнения
+\end_layout
+
+\begin_layout Standard
+Для разработки процедур, выполняемых на видеокарте, используется язык C
+ со специальными расширениями, и компилятор разработанный NVidia.
+ Другие языки не поддерживаются.
+\end_layout
+
+\begin_layout Standard
+Порожденный компилятором ассемблерный код загружается с помощью библиотеки,
+ взаимодействующей с драйвером видеокарты.
+ При этом он транслируется в машинный код соответствующей видеокарты
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+В этот момент происходит распределение реальных регистров.
+ Ассемблер использует форму SSA.
+\end_layout
+
+\end_inset
+
+.
+ Эта же библиотека отвечает за выделение памяти на видеокарте и копирование
+ данных, а также позволяет запустить загруженные процедуры на исполнение,
+ передав им нужные параметры.
+\end_layout
+
+\begin_layout Section
+Генерация кода
+\end_layout
+
+\begin_layout Standard
+Наиболее удобным способом решения проблем с неоптимальными схемами индексировани
+я массивов и итерации, а также адаптации программы к различным архитектурам,
+ является генерация низкоуровневого кода из высокоуровневой спецификации.
+ В случае если спецификация достаточно абстрактна, при изменении архитектуры
+ достаточно изменить генератор кода.
+ Кроме этого, схема, основанная на генерации, может помочь изолировать низкоуров
+невые параметры от основной логики программы.
+\end_layout
+
+\begin_layout Subsection
+Язык Лисп
+\end_layout
+
+\begin_layout Standard
+Несмотря на 50-летнюю историю, язык Лисп до сих пор не потерял актуальность.
+ В то время как многие его особенности, вроде сборки мусора и динамической
+ типизации, были внедрены в новых популярных языках, он до сих пор лидирует
+ по легкости своей модификации.
+\end_layout
+
+\begin_layout Standard
+Это связано с изоляцией синтаксиса и семантики программы, а именно, использовани
+ем для записи кода простой структуры из вложенных списков.
+ Такая организация позволяет легко выполнять произвольную трансформацию
+ кода между синтаксическим анализом и компиляцией, что напрямую поддерживается
+ стандартом языка в форме макросов.
+\end_layout
+
+\begin_layout Standard
+В отличие от примитивных макросов языка C, макросы ANSI Common Lisp
+\begin_inset CommandInset citation
+LatexCommand cite
+key "cl-hspec"
+
+\end_inset
+
+ являются полноценными функциями, которые отличаются от обычных только тем,
+ что выполняются на этапе компиляции и манипулируют выражениями программы.
+ Они также могут вызывать обычные функции, в том числе из того же исходного
+ файла, и использоваться сразу после объявления
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+Это отличается от систем вроде camlp4
+\begin_inset CommandInset citation
+LatexCommand cite
+key "camlp4"
+
+\end_inset
+
+, где модификации синтаксиса компилируются отдельно и работают в среде,
+ полностью отличной от основной программы.
+\end_layout
+
+\end_inset
+
+.
+ Значительная часть операторов из стандарта языка на самом деле реализуется
+ с помощью макросов.
+\end_layout
+
+\begin_layout Standard
+Язык также позволяет модифицировать работу самого синтаксического анализатора
+ с помощью регистрации обработчиков для определенных комбинаций символов.
+\end_layout
+
+\begin_layout Subsubsection
+Преимущества для проекта
+\end_layout
+
+\begin_layout Standard
+В связи с тем что Лисп -- язык общего назначения, который при этом удобен
+ для символьной обработки выражений, его можно использовать как для реализации
+ генератора кода, так и для вычислительной программы.
+ Это позволяет ограничиться одной средой разработки.
+\end_layout
+
+\begin_layout Standard
+Кроме этого, за счет интеграции генератора кода в полноценный язык, его
+ реализацию можно развивать постепенно, обращаясь к основному языку для
+ выполнения редко используемых вычислительной программой, но необходимых
+ операций.
+\end_layout
+
+\begin_layout Standard
+Наконец, встроенная библиотека языка позволяет не заботиться о ручной реализации
+ управления памятью, обработки ошибок и многопоточности.
+\end_layout
+
+\begin_layout Subsubsection
+Embeddable Common Lisp
+\end_layout
+
+\begin_layout Standard
+Использованная в проекте реализация языка
+\begin_inset CommandInset citation
+LatexCommand cite
+key "ref-ecl"
+
+\end_inset
+
+ как таковая заметно отстает от наиболее популярных свободно распространяемых
+ реализаций как по производительности, так и по совместимости со сторонними
+ библиотеками.
+ Однако она легче всех интегрируется с кодом на C, что и является целью
+ ее разработчиков.
+\end_layout
+
+\begin_layout Standard
+В частности, поскольку при компиляции она транслирует код на язык C и вызывает
+ внешний компилятор для получения загружаемой библиотеки, она позволяет
+ вставлять в код на языке Лисп фрагменты программы на C, аналогично поддержке
+ ассемблера компиляторами C и C++.
+ Это позволяет генератору кода абсолютно прозрачным образом интегрировать
+ результат своей работы в среду.
+\end_layout
+
+\begin_layout Subsection
+Расширения языка
+\end_layout
+
+\begin_layout Standard
+В качестве средств высокоуровневой спецификации вычислительного алгоритма,
+ язык был расширен следующими конструкциями.
+\end_layout
+
+\begin_layout Subsubsection
+Синтаксис ввода формул
+\end_layout
+
+\begin_layout Standard
+Язык Лисп использует префиксный синтаксис, который неудобен для ввода и
+ понимания больших формул.
+ Кроме этого, формулы в такой записи нельзя получить средствами систем вроде
+ Maple
+\begin_inset CommandInset citation
+LatexCommand cite
+key "maple"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Для того чтобы обойти эту проблему, было реализовано синтаксическое расширение,
+ распознающее формулы в инфиксной записи внутри фигурных скобок:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+lstparams "basicstyle={\footnotesize},language=Lisp,showstringspaces=false"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+ { NEW_DT[i,MW+1] := (TMP_ANU[MW-1]*TMP_EPS[MW+1]+TMP_ANU[MW+1])
+\end_layout
+
+\begin_layout Plain Layout
+
+ / (1.0-TMP_EPS[MW+1]*TMP_EPS[MW-1]) }
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Синтаксическое расширение распознает арифметические операции, обращения
+ к массивам, вызовы функций, условия с операциями сравнения, и последовательност
+и присваиваний.
+\end_layout
+
+\begin_layout Subsubsection
+Виртуальные массивы
+\end_layout
+
+\begin_layout Standard
+Для оптимизации размещения массивов в памяти используется система виртуальных
+ массивов.
+ В момент их декларации задается набор логических размерностей, а также
+ желаемый способ физической организации.
+ Виртуальные массивы позволяют менять порядок физических индексов относительно
+ логических, а также модифицировать структуру самих измерений одним из следующих
+ способов:
+\end_layout
+
+\begin_layout Enumerate
+Пропускать все элементы, кроме следующих с определенным шагом.
+ Обращение к промежуточным индексам является ошибкой.
+\end_layout
+
+\begin_layout Enumerate
+Добавлять дополнительное скрытое физическое измерение константного размера,
+ и распределять элементы по полученной паре измерений, используя остаток
+ от деления на эту константу.
+ При этом итерация с шагом равным константе преобразуется в единичный шаг
+ на физическом уровне.
+\end_layout
+
+\begin_layout Standard
+Примеры деклараций:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+lstparams "basicstyle={\footnotesize},language=Lisp"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+ (def-multivalue DR ((i 1 (1+ N1) :by 2) (k 1 (1+ MW) :by 2)))
+\end_layout
+
+\begin_layout Plain Layout
+
+ (def-multivalue PL ((i 1 (1+ N1)) (k 1 (+ MW 2) :bands 2)))
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Для обращения к виртуальным массивам используется макрос
+\family typewriter
+iref
+\family default
+, аналогичный по внешнему интерфейсу оператору доступа к стандартным массивам
+
+\family typewriter
+aref
+\family default
+.
+ Система старается обнаруживать явные ошибки индексирования статически,
+ и предупреждать о них на этапе компиляции.
+
+\end_layout
+
+\begin_layout Standard
+Также предусмотрена возможность автоматической подстановки выражения вместо
+ массива:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+lstparams "basicstyle={\footnotesize},language=Lisp"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+ (def-multivalue-macro T_ (i k) { T0[k] })
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsubsection
+Итерация по логическим размерностям
+\end_layout
+
+\begin_layout Standard
+Для облегчения работы с виртуальными массивами предусмотрен оператор итерации
+ по логическим индексам.
+ Его параметрами являются имя виртуального массива и список его логических
+ индексов.
+ В результате раскрытия макросов генерируется ряд циклов по физическим размернос
+тям массива, а вхождения имен логических индексов в тело цикла заменяются
+ на соответствующие выражения.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+lstparams "basicstyle={\footnotesize},language=Lisp"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+ (do-indexes OUT_U (i k)
+\end_layout
+
+\begin_layout Plain Layout
+
+ (format vel (formatter "~12,3E ~12,3E ~14,5E ~14,5E~%")
+\end_layout
+
+\begin_layout Plain Layout
+
+ (iref xcoord i) (iref zcoord k)
+\end_layout
+
+\begin_layout Plain Layout
+
+ (iref OUT_U i k) (iref OUT_V i k)))
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+В случае если индексы используются для доступа к виртуальным массивам, при
+ раскрытии
+\family typewriter
+iref
+\family default
+ эти выражения упрощаются до использования физических индексов напрямую.
+
+\end_layout
+
+\begin_layout Standard
+Порядок индексов в заголовке цикла задает вложенность, а соответствие размерност
+ям целевого массива определяется по совпадению имен индексов с идентификаторами
+ в его декларации.
+ Кроме этого, оператор позволяет задавать шаг и направление итерации, а
+ также пропускать фиксированное количество элементов с обоих концов диапазона.
+\end_layout
+
+\begin_layout Subsubsection
+Оператор вычисления формулы
+\end_layout
+
+\begin_layout Standard
+Наконец, система предоставляет оператор для вычисления массива по определенной
+ формуле.
+ Именно в нем происходит генерация оптимизированного кода.
+ Внешне его заголовок похож на оператор цикла, но в данном случае порядок
+ индексов должен соответствовать порядку соответствующих измерений, а вложенност
+ь циклов определяется автоматически.
+ В примере можно увидеть как задается шаг цикла
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+Запись
+\begin_inset Quotes eld
+\end_inset
+
+
+\family typewriter
+(* число)
+\family default
+
+\begin_inset Quotes erd
+\end_inset
+
+ означает, что задается шаг, но не направление.
+\end_layout
+
+\end_inset
+
+ и пропуск элементов:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+lstparams "basicstyle={\footnotesize},language=Lisp"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+ (compute PL ((i :skip (1 1) :step (* 2))
+\end_layout
+
+\begin_layout Plain Layout
+
+ (k :step (* 2)))
+\end_layout
+
+\begin_layout Plain Layout
+
+ { t3*t10/2.+2.*t1*_grp(t2/t3)*t12 }
+\end_layout
+
+\begin_layout Plain Layout
+
+ :parallel i
+\end_layout
+
+\begin_layout Plain Layout
+
+ :with { t1 := PL[i+1,k];
+\end_layout
+
+\begin_layout Plain Layout
+
+ ...
+ })
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+С помощью дополнительных именованных параметров можно объявлять временные
+ переменные для использования в основной формуле, задавать зависимость между
+ итерациями по определенному индексу, контролировать распараллеливание в
+ режиме SSE и задавать дополнительные флаги для CUDA.
+ Путем использования последовательности присваиваний вместо основного выражения
+ можно одновременно обновлять несколько массивов, а указав в заголовке константу
+ или арифметическое выражение вместо индекса можно избежать генерации соответств
+ующего цикла.
+\end_layout
+
+\begin_layout Standard
+В случае невозможности транслировать выражение для SSE или CUDA, оператор
+ раскрывается в эквивалентный цикл на языке Лисп.
+ Это позволяет использовать тот же синтаксис и для операций, не поддержанных
+ генератором кода:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+lstparams "basicstyle={\footnotesize},language=Lisp"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+ (compute AMU (k) (call-fun molecular-mass (iref zcoord k)))
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Оптимизация
+\end_layout
+
+\begin_layout Standard
+Для улучшения производительности система использует определенный набор техник
+ оптимизации.
+ Часть из них направлена на реструктуризацию формул, часть является специфичной
+ для адаптации их к выполнению на процессоре видеокарты.
+\end_layout
+
+\begin_layout Subsection
+Реструктуризация выражений
+\end_layout
+
+\begin_layout Standard
+Помимо арифметического упрощения индексных выражений, необходимого для эффективн
+ой реализации перехода от логических к физическим индексам и наоборот, программа
+ выполняет ряд шагов, направленных на улучшение эффективности вычислений:
+\end_layout
+
+\begin_layout Enumerate
+Деревья из вложенных ассоциативно-коммутативных операций (сложения и умножения)
+ уплощаются, а их операнды сортируются для выявления реальной структуры
+ выражений.
+ В ситуациях, когда это недопустимо, может быть использован специальный
+ оператор
+\family typewriter
+_grp(...)
+\family default
+
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+В отсутствие такой конструкции, перестановка операндов может в итоге понизить
+ полезность системы т.к.
+ она в некоторых случаях недопустима из-за округления и ограничений по диапазону
+ вещественных чисел.
+\end_layout
+
+\end_inset
+
+, действующий как не подлежащие разбиению скобки.
+\end_layout
+
+\begin_layout Enumerate
+Выполняется простейшее вынесение общих сомножителей за скобки, сокращение
+ противоположных слагаемых и множителей.
+\end_layout
+
+\begin_layout Enumerate
+Выполняется упрощение выражений, используемых для ветвления по знаку
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+В модели атмосферы, для оптимизации которой был разработан данный генератор
+ кода, часто используется ступенчатая функция (ifsign x 0.0 0.5 1.0).
+ В ее аргументах нередко содержатся константы и другие сомножители, не влияющие
+ на знак.
+\end_layout
+
+\end_inset
+
+, за счет использования предоставленной программистом информации о знаке
+ значений, хранящихся в переменных и массивах.
+\end_layout
+
+\begin_layout Enumerate
+Уплощенные группы слагаемых и множителей разбиваются с учетом их зависимости
+ от индексов разного уровня вложенности циклов.
+ Это улучшает эффективность вынесения из циклов инвариантных выражений.
+\end_layout
+
+\begin_layout Enumerate
+Группы слагаемых и множителей дополнительно разбиваются с целью повышения
+ эффективности выделения общих подвыражений.
+ Для этого выполняется их попарное сравнение и выделение обнаруженных таким
+ образом общих подмножеств.
+ При работе используется очередь подмножеств, упорядоченная по убыванию
+ их размера.
+\end_layout
+
+\begin_layout Enumerate
+Выполняется выделение общих подвыражений с распределением кода по уровням
+ вложенности циклов.
+\end_layout
+
+\begin_layout Enumerate
+Уплощенная структура преобразуется в бинарное дерево с учетом необходимости
+ балансировки и минимизации числа операций деления.
+\end_layout
+
+\begin_layout Subsection
+Особенности CUDA
+\end_layout
+
+\begin_layout Standard
+Особенности архитектуры графического процессора требуют применения дополнительны
+х шагов оптимизации.
+ Их можно разделить на меры по улучшению эффективности использования памяти,
+ и реорганизации структуры циклов.
+\end_layout
+
+\begin_layout Subsubsection
+Эффективное использование памяти
+\end_layout
+
+\begin_layout Standard
+Графический процессор содержит целый ряд различных видов памяти и способов
+ доступа к ней.
+ Их эффективное использование необходимо для получения хорошей производительност
+и.
+ В частности, генератор кода:
+\end_layout
+
+\begin_layout Itemize
+Поддерживает использование механизма текстур для чтения из массивов.
+\end_layout
+
+\begin_deeper
+\begin_layout Standard
+Текстуры предоставляют возможность кеширования данных, умешьная нагрузку
+ на интерфейс с внешней памятью.
+ В связи с неясностью границ эффективности данной оптимизации, ее использование
+ необходимо задавать вручную.
+ Однако генерация кода позволяет упростить это до простого указания списка
+ имен массивов, к которым ее нужно применить.
+\end_layout
+
+\end_deeper
+\begin_layout Itemize
+Автоматически выявляет возможность размещения временного массива в регистрах.
+\end_layout
+
+\begin_deeper
+\begin_layout Standard
+Временные массивы используются для реализации переноса значений между итерациями
+, а также выделения параллелизуемых частей циклов с таким переносом.
+ В случае когда каждый конкретный элемент массива используется только в
+ одном потоке, массив можно разместить в локальных регистрах.
+ Это позволяет уменьшить расход общей памяти и избежать необходимости синхрониза
+ции.
+\end_layout
+
+\end_deeper
+\begin_layout Itemize
+Автоматически размещает постоянные значения в общей памяти.
+\end_layout
+
+\begin_deeper
+\begin_layout Standard
+Значения, одинаковые для всех потоков блока, могут быть размещены в общей
+ памяти.
+ Предельным случаем такого размещения являются параметры, которые задаются
+ один раз при запуске процедуры, и просто копируются планировщиком в каждый
+ блок.
+ Значения, которые зависят от индекса блока, могут быть посчитаны одним
+ из потоков в начале его работы.
+ Это преобразование позволяет уменьшить число необходимых регистров.
+\end_layout
+
+\end_deeper
+\begin_layout Subsubsection
+Разбиение направленных циклов
+\end_layout
+
+\begin_layout Standard
+В норме самый внутренний цикл распределяется генератором кода по потокам
+ внутри блока и выполняется параллельно.
+ Однако если задача требует передачи значения между итерациями, они вынужденно
+ выполняются последовательно.
+\end_layout
+
+\begin_layout Standard
+В связи с особенностями организации вычислений в процессоре, такое упорядочивани
+е повышает стоимость каждой команды в теле цикла более чем на порядок.
+ Таким образом, в отличие от случая вычислений на центральном процессоре,
+ эффективность требует вынесения за пределы цикла всех без исключения операций,
+ которые можно выполнить параллельно.
+\end_layout
+
+\begin_layout Standard
+Возникновение при этом временных переменных не представляет значительной
+ проблемы, т.к.
+ все они размещаются в локальных регистрах потоков.
+\end_layout
+
+\begin_layout Standard
+Для выполнения данной оптимизации генератор кода выявляет переменные, которые
+ одновременно читаются и пишутся в цикле, и оставляет в упорядоченной части
+ только действия, которые участвуют в цепочке зависимостей.
+\end_layout
+
+\begin_layout Subsubsection
+Перестановка операций в теле цикла
+\end_layout
+
+\begin_layout Standard
+Опыт показывает, что перестановка операций в теле самого внутреннего цикла
+ способна заметно понизить потребность кода в регистрах, что важно для достижени
+я оптимальной производительности.
+\end_layout
+
+\begin_layout Standard
+Для выполнения перестановки все выражения разбиваются на элементарные операции
+ и конвертируются в последовательность присваиваний временным переменным.
+ После этого присваивания перераспределяются с использованием следующих
+ эвристик:
+\end_layout
+
+\begin_layout Enumerate
+Для упорядочивания используется очередь из операций, все операнды которых
+ уже посчитаны.
+\end_layout
+
+\begin_layout Enumerate
+На каждом шаге выбирается операция с максимальным числом операндов.
+\end_layout
+
+\begin_layout Enumerate
+Если таких в очереди несколько, выбирается идущая первой в исходном порядке
+\begin_inset Foot
+status collapsed
+
+\begin_layout Plain Layout
+Данный порядок соответствует двухуровневому обходу в глубину слева направо:
+ сначала по общим подвыражениям, а внутри по всем операциям.
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Эффективность таких простых эвристик может свидетельствовать о том, что
+ механизм распределения регистров в компиляторе NVidia использует алгоритм,
+ не поддерживающий возможность существенной реорганизации последовательности
+ операций.
+ Кроме этого, в некоторых случаях число реально использованных регистров
+ зависит от заданного ограничения на их количество.
+\end_layout
+
+\begin_layout Section
+Результаты
+\end_layout
+
+\begin_layout Standard
+Генератор кода был использован для оптимизации работы реализации двумерной
+ модели атмосферы
+\begin_inset CommandInset citation
+LatexCommand cite
+key "model"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Itemize
+Режим SSE дал ускорение в 14 раз относительно исходной реализации на языке
+ Фортран с использованием OpenMP.
+\end_layout
+
+\begin_deeper
+\begin_layout Enumerate
+Ускорение в 4 раза является ожидаемым результатом использования векторных
+ команд.
+\end_layout
+
+\begin_layout Enumerate
+Упрощение выражений дало выигрыш порядка 40%
+\end_layout
+
+\begin_layout Enumerate
+Оставшиеся 2.5 раза, вероятно, можно объяснить более эффективным порядком
+ обхода памяти, удалением лишних вызовов функций, и.т.п.
+\end_layout
+
+\end_deeper
+\begin_layout Itemize
+Режим CUDA на видеокарте GeForce GTX 275 дал дополнительное ускорение до
+ 5 раз относительно варианта SSE на процессоре Intel Core 2 Quad 2.66 GHz,
+ запущенного в 3 потока.
+ Точное значение ускорения растет по мере увеличения размера массивов.
+\end_layout
+
+\begin_layout Standard
+Сравнение спецификаций производительности обоих процессоров позволяют ожидать
+ предельное ускорение порядка 26 раз.
+ Однако в случае невозможности использования команд MADD на видеокарте данный
+ показатель падает до числа 8.
+ Кроме того, грубая оценка показывает, что зависимости между итерациями
+ внутреннего цикла в используемой данной моделью вычислительной схеме может
+ легко привести к замедлению в 1.5--2 раза.
+\end_layout
+
+\begin_layout Bibliography
+\begin_inset CommandInset bibitem
+LatexCommand bibitem
+key "ref-ecl"
+
+\end_inset
+
+Реализация Embeddable Common Lisp,
+\begin_inset Newline newline
+\end_inset
+
+http://ecls.sourceforge.net/
+\end_layout
+
+\begin_layout Bibliography
+\begin_inset CommandInset bibitem
+LatexCommand bibitem
+key "maple"
+
+\end_inset
+
+Система компьютерной алгебры Maple,
+\begin_inset Newline newline
+\end_inset
+
+http://www.maplesoft.com/
+\begin_inset Newline newline
+\end_inset
+
+http://en.wikipedia.org/wiki/Maple_%28software%29
+\end_layout
+
+\begin_layout Bibliography
+\begin_inset CommandInset bibitem
+LatexCommand bibitem
+key "msdn-sse"
+
+\end_inset
+
+Встроенные функции MMX, SSE и SSE2
+\begin_inset Newline newline
+\end_inset
+
+http://msdn.microsoft.com/en-us/library/y0dh78ez%28VS.80%29.aspx
+\end_layout
+
+\begin_layout Bibliography
+\begin_inset CommandInset bibitem
+LatexCommand bibitem
+key "cuda-intro"
+
+\end_inset
+
+Документация и средства разработки CUDA.
+\begin_inset Newline newline
+\end_inset
+
+http://www.nvidia.com/object/cuda_learn.html
+\end_layout
+
+\begin_layout Bibliography
+\begin_inset CommandInset bibitem
+LatexCommand bibitem
+key "cl-hspec"
+
+\end_inset
+
+Спецификация ANSI Common Lisp,
+\begin_inset Newline newline
+\end_inset
+
+http://www.lispworks.com/documentation/common-lisp.html
+\end_layout
+
+\begin_layout Bibliography
+\begin_inset CommandInset bibitem
+LatexCommand bibitem
+key "camlp4"
+
+\end_inset
+
+Препроцессор CamlP4,
+\begin_inset Newline newline
+\end_inset
+
+http://caml.inria.fr/pub/docs/manual-camlp4/index.html
+\end_layout
+
+\begin_layout Bibliography
+\begin_inset CommandInset bibitem
+LatexCommand bibitem
+key "model"
+
+\end_inset
+
+Kshevetskii S P, Gavrilov N M.
+ Vertical propagation, breaking and effects of nonlinear gravity waves in
+ the atmosphere.
+ J Atmos Sol Terr Phys, 2005, 67, 1014---1030
+\end_layout
+
+\end_body
+\end_document
View
BIN  doc/report.ru.pdf
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.