OpenHMPP - OpenHMPP

OpenHMPP (HMPP[1] для гибридного многоядерного параллельного программирования) - стандарт программирования для гетерогенные вычисления. На основе набора директив компилятора стандарт представляет собой модель программирования, предназначенную для обработки аппаратные ускорители без сложности, связанной с Программирование на GPU. Этот подход, основанный на директивах, был реализован, потому что они обеспечивают свободную связь между кодом приложения и использованием аппаратного ускорителя (HWA).

Вступление

Модель программирования на основе директив OpenHMPP предлагает синтаксис для разгрузки вычислений на аппаратных ускорителях и для оптимизации перемещения данных в / из аппаратной памяти.

Модель основана на работах, инициализированных CAPS (компилятор и архитектура для встроенных и суперскалярных процессоров), общий проект от INRIA, CNRS, то Реннский университет 1 и INSA в Ренне.

Концепция OpenHMPP

OpenHMPP основан на концепции кодлетов, функций, которые могут удаленно выполняться на HWA.

Концепция кодлета OpenHMPP

Кодлет имеет следующие свойства:

  1. Это чистая функция.
    • Не содержит статический или же летучий объявления переменных и не ссылаются на какие-либо глобальные переменные, кроме случаев, когда они были объявлены «резидентной» директивой HMPP.
    • Он не содержит вызовов функций с невидимым телом (которое не может быть встроено). Это включает использование библиотек и системных функций, таких как malloc, printf, ...
    • Каждый вызов функции должен ссылаться на статическую чистую функцию (без указателей на функции).
  2. Он не возвращает никакого значения (функция void в C или подпрограмма в Фортран ).
  3. Количество аргументов должно быть фиксированным (т.е. это не может быть вариативная функция как в stdarg.h в C).
  4. Это не рекурсивно.
  5. Предполагается, что его параметры не имеют алиасинга (см. Сглаживание (вычисления) и Смещение указателя ).
  6. Он не содержит директив callite (то есть RPC к другому кодлету) или других директив HMPP.

Эти свойства гарантируют, что кодлет RPC может удаленно выполняться с помощью HWA. Этот RPC и связанные с ним передачи данных могут быть асинхронными.

Codelet RPC

HMPP обеспечивает синхронный и асинхронный RPC. Реализация асинхронной работы зависит от оборудования.

Синхронный и асинхронный RPC

Модель памяти HMPP

HMPP рассматривает два адресных пространства: одно хост-процессор и память HWA.

Модель памяти HMPPP

Концепция директив

Директивы OpenHMPP можно рассматривать как «метаинформацию», добавленную в исходный код приложения. Это безопасная метаинформация, т.е.они не меняют исходное поведение кода. Они касаются удаленного выполнения (RPC) функции, а также передачи данных в / из памяти HWA.

В таблице ниже представлены директивы OpenHMPP. Директивы OpenHMPP удовлетворяют различные потребности: некоторые из них предназначены для объявлений, а другие - для управления выполнением.

Инструкции потока управленияДирективы по управлению данными
Декларациикодлет
группа
резидент
карта
mapbyname
Операционные директивыпозывной
синхронизировать
область, край
выделить
релиз
расширенная нагрузка
делегированный магазин

Понятие набора директив

Одним из фундаментальных моментов подхода HMPP является концепция директив и связанных с ними меток, которая позволяет раскрыть целостную структуру для всего набора директив, распространяемых в приложении.

Есть два вида этикеток:

  • Один, связанный с кодлетом. В общем, директивы, несущие этот вид меток, ограничиваются управлением только одним кодлетом (называемым автономным кодлетом в остальной части документа, чтобы отличать его от группы кодлетов).
  • Один связан с группой кодлетов. Эти метки обозначаются следующим образом: «», где «LabelOfGroup» - это имя, указанное пользователем. В общем, директивы с меткой этого типа относятся ко всей группе. Концепция группы зарезервирована для класса проблем, который требует особого управления данными во всем приложении для достижения производительности.

Синтаксис директив OpenHMPP

Чтобы упростить обозначения, обычные выражения будет использоваться для описания синтаксиса директив HMPP.

Приведенное ниже цветовое соглашение используется для описания синтаксических директив:

  • Зарезервированные ключевые слова HMPP находятся в зеленый;
  • Элементы грамматики, которые можно отклонять в ключевых словах HMPP, находятся в красный;
  • Пользовательские переменные остаются черными.

Общий синтаксис

Общий синтаксис директив OpenHMPP:

  • Для языка C:
#pragma hmpp <grp_label> [codelet_label]? Directive_type [,Directive_parameters]* [&]
  • Для языка FORTRAN:
! $ hmpp <grp_label> [codelet_label]? Directive_type [,Directive_parameters]* [&]

Где:

  • <grp_label>: - уникальный идентификатор, называющий группу кодлетов. В случаях, когда в приложении не определены группы, этот ярлык можно просто пропустить. Название юридической метки должно соответствовать следующей грамматике: [a-z, A-Z, _] [a-z, A-Z, 0-9, _] *. Обратите внимание, что символы «<>» относятся к синтаксису и являются обязательными для такого типа меток.
  • codelet_label: - уникальный идентификатор кодлета. Название юридической метки должно соответствовать следующей грамматике: [a-z, A-Z, _] [a-z, A-Z, 0-9, _] *
  • директива: имя директивы;
  • Directive_parameters: обозначает некоторые параметры, связанные с директивой. Эти параметры могут быть разных типов и указывать либо некоторые аргументы, передаваемые директиве, либо режим выполнения (например, асинхронный или синхронный);
  • [&]: это символ, используемый для продолжения директивы на следующей строке (то же самое для C и FORTRAN).

Параметры директивы

Параметры, связанные с директивой, могут быть разных типов. Ниже приведены параметры директивы, определенные в OpenHMPP:

  • версия = major.minor [.micro]: указывает версию директив HMPP, которую должен учитывать препроцессор.
  • args [arg_items] .size = {dimsize [, dimsize] *}: определяет размер нескалярного параметра (массива).
  • args [arg_items] .io = [вход | выход | вход]: указывает, что указанные аргументы функции являются входными, выходными или обоими. По умолчанию вводятся неквалифицированные аргументы.
  • cond = "expr": задает условие выполнения в виде логического выражения C или Fortran, которое должно быть истинным, чтобы начать выполнение группы или кодлетов.
  • target = target_name [: target_name] *: указывает, какие цели попытаться использовать в заданном порядке.
  • асинхронный: указывает, что выполнение кодлета не блокируется (по умолчанию синхронно).
  • args [] .advancedload = true: указывает, что указанные параметры предварительно загружены. Предварительно могут быть загружены только параметры in или inout.
  • args [arg_items] .noupdate = true: это свойство указывает, что данные уже доступны на HWA и поэтому передача не требуется. Когда это свойство установлено, передача рассматриваемого аргумента не выполняется.
  • args [] .addr = "": <expr> это выражение, которое дает адрес данных для загрузки.
  • args [] .const = true: указывает, что аргумент должен быть загружен только один раз.

Директивы OpenHMPP

Директивы для объявления и выполнения кодлета

А кодлет Директива объявляет, что вычисление будет удаленно выполняться на аппаратном ускорителе. кодлет директива:

  • Этикетка кодлета является обязательной и должна быть уникальной в приложении.
  • Метка группы не требуется, если группа не определена.
  • Директива codelet вставляется непосредственно перед объявлением функции.

Синтаксис директивы:

#pragma hmpp <grp_label> codelet_label кодлет                             [, версия = major.minor [.micro]?]? [, args [arg_items] .io =[[в|вне|inout]]*                            [, args [arg_items] .size = {dimsize [, dimsize] *}]*                            [, args [arg_items] .const = true]*                            [, cond = "expr"] [, цель =target_name[:target_name]*]

К функции можно добавить более одной директивы codelet, чтобы указать разные варианты использования или разные контексты выполнения. Однако может быть только одна директива кодлета для данной метки места вызова.

В позывной Директива определяет, как использовать кодлет в данной точке программы.

Синтаксис директивы:

#pragma hmpp <grp_label> codelet_label позывной                     [, асинхронный]?                     [, args [arg_items] .size = {dimsize [, dimsize] *}]*                     [, args [arg_items] .advancedload =[[истинный|ложный]]*                     [, args [arg_items] .addr = "expr"]*                     [, args [arg_items] .noupdate = true]*

Пример показан здесь:

 / * объявление кодлета * / #pragma hmpp simple1 codelet, args [outv] .io = inout, target = CUDA статический пустота Матвек(int sn, int см, плавать inv[см], плавать дюйм[sn][см], плавать *outv){     int я, j;     за (я = 0 ; я < см ; я++) {       плавать темп = outv[я];       за (j = 0 ; j < sn ; j++) {         темп += inv[j] * дюйм[я][ j];     }    outv[я] = темп;  }    int основной(int argc, char **argv) {    int п;    ........    / * использование кодлета * /  #pragma hmpp simple1 callite, args [outv] .size = {n}.  Матвек(п, м, myinc, дюйм, myoutv);    ........  }

В некоторых случаях требуется специальное управление данными во всем приложении (оптимизация движения данных CPU / GPU, общие переменные ...).

В группа Директива позволяет объявить группу кодлетов. Параметры, определенные в этой директиве, применяются ко всем кодлетам, принадлежащим группе. Синтаксис директивы:

#pragma hmpp <grp_label> группа                           [, версия = <главный>. <второстепенный> [. <микро>]?]? [, цель = target_name[:target_name]*]]?                           [, cond = «expr]?

Директивы передачи данных для оптимизации коммуникационных накладных расходов

При использовании HWA основным узким местом часто является передача данных между HWA и главным процессором.
Чтобы ограничить служебные данные связи, передачи данных могут перекрываться с последовательными выполнениями одного и того же кодлета с использованием асинхронного свойства HWA.

  • директива allocate

В выделить Директива блокирует HWA и выделяет необходимый объем памяти.

#pragma hmpp <grp_label> выделить [, args [arg_items] .size = {dimsize [, dimsize] *}]*
  • директива о выпуске

В релиз Директива указывает, когда следует освободить HWA для группы или автономного кодлета.

#pragma hmpp <grp_label> выпуск
  • директива advancedload

В расширенная нагрузка Директива выполняет предварительную выборку данных перед удаленным выполнением кодлета.

#pragma hmpp <grp_label> [codelet_label]? расширенная нагрузка                  , args [arg_items]                  [, args [arg_items] .size = {dimsize [, dimsize] *}]*                  [, args [arg_items] .addr = "expr"]*                  [, args [arg_items] .section = {[subscript_triplet,]+}]*                  [,асинхронный]
  • директива делегированного хранилища

В делегированный магазин Директива является барьером синхронизации для ожидания завершения выполнения асинхронного кодлета, а затем для загрузки результатов.

#pragma hmpp <grp_label> [codelet_label]? делегированный магазин                 , args [arg_items]                [, args [arg_items] .addr = "expr"]*                [, args [arg_items] .section = {[subscript_triplet,]+}]*
  • Асинхронные вычисления

В синхронизировать Директива указывает, что нужно дождаться завершения выполнения асинхронного вызова. Для директивы synchronize метка кодлета всегда обязательна, а метка группы требуется, если кодлет принадлежит к группе.

#pragma hmpp <grp_label> codelet_label синхронизировать
  • Пример

В следующем примере инициализация устройства, выделение памяти и загрузка входных данных выполняются только один раз вне цикла, а не на каждой итерации цикла.

В синхронизировать Директива позволяет дождаться завершения асинхронного выполнения кодлета перед запуском следующей итерации. Наконец делегированный магазин Директива вне цикла загружает результат sgemm.

 int основной(int argc, char **argv) {  #pragma hmpp sgemm allocate, args [vin1; vin2; vout] .size = {размер, размер} #pragma hmpp sgemm advancedload, args [vin1; vin2; vout], args [m, n, k, alpha, beta]    за ( j = 0 ; j < 2 ; j ++) {    #pragma hmpp sgemm callite, асинхронный, args [vin1; vin2; vout] .advancedload = true, args [m, n, k, alpha, beta] .advancedload = true    sgemm (размер, размер, размер, альфа, vin1, vin2, бета, ваут);    #pragma hmpp sgemm synchronize }  #pragma hmpp sgemm delegatedstore, args [vout] #pragma hmpp sgemm release

Обмен данными между кодлетами

Эти директивы сопоставляют вместе все аргументы, использующие данное имя для всей группы.

Типы и размеры всех сопоставленных аргументов должны быть идентичными.

В карта Директива отображает несколько аргументов на устройстве.

#pragma hmpp <grp_label> map, args [arg_items]

Эта директива очень похожа на карта директиве, за исключением того, что отображаемые аргументы прямо указываются по их имени. В mapbyname директива эквивалентна множественному карта директивы.

#pragma hmpp <grp_label> mapbyname [,variableName] +

Глобальная переменная

В резидент Директива объявляет некоторые переменные глобальными внутри группы. Затем к этим переменным можно будет получить прямой доступ из любого кодлета, принадлежащего группе. Эта директива применяется к оператору объявления сразу после него в исходном коде.

Синтаксис этой директивы:

#pragma hmpp <grp_label> резидент                [, args [::var_name] .io =[[в|вне|inout]]*               [, args [::var_name] .size = {dimsize [, dimsize] *}]*               [, args [::var_name] .addr = "expr"]*               [, args [::var_name] .const = true]*

Обозначение :: var_name с приставкой ::, указывает переменную приложения, объявленную как резидентную.

Разгон регионов

Регион - это слияние директив codelet / callite. Цель состоит в том, чтобы избежать реструктуризации кода для построения кодлета. Следовательно, все атрибуты, доступные для кодлет или же позывной директивы могут использоваться на регионы директивы.

На языке C:

#pragma hmpp [<Моя группа>] [метка] область, край                                    [, args [arg_items] .io =[[в|вне|inout]]*                           [, cond = "expr"]<                           [, args [arg_items] .const = true]*                           [, цель =target_name[:target_name]*]                           [, args [arg_items] .size = {dimsize [,dimsize] *}]*                           [, args [arg_items] .advancedload =[[истинный|ложный]]*                           [, args [arg_items] .addr = "expr"]*                           [, args [arg_items] .noupdate = true]*                           [, асинхронный]?                           [, частный = [arg_items]] * {ЗАЯВЛЕНИЯ О БЛОКЕ C}

Реализации

Открытый стандарт OpenHMPP основан на HMPP версии 2.3 (май 2009 г., предприятие CAPS).

Модель программирования на основе директив OpenHMPP реализована в:

  • Компиляторы CAPS, компиляторы CAPS Entreprise для гибридных вычислений
  • PathScale ENZO Compiler Suite (поддержка графических процессоров NVIDIA)

OpenHMPP используется HPC актеры[ВОЗ? ] в нефти и газе,[нужна цитата ] Энергия,[нужна цитата ] Производство,[нужна цитата ] Финансы,[нужна цитата ] Образование и исследования.[нужна цитата ]

Смотрите также

Рекомендации

  1. ^ Долбо, Ромен; Бихан, Стефан; Боден, Франсуа (4 октября 2007 г.). HMPP: гибридная многоядерная среда параллельного программирования (PDF). Практикум по универсальной обработке на графических процессорах. Архивировано из оригинал (PDF) 16 января 2014 г.. Получено 14 января 2014.

внешняя ссылка