OpenHMPP (HMPP [1] для гибридного многоядерного параллельного программирования) - стандарт программирования для гетерогенных вычислений . Стандартная модель программирования, основанная на наборе директив компилятора, предназначена для работы с аппаратными ускорителями без сложностей, связанных с программированием на GPU . Этот подход, основанный на директивах, был реализован, потому что они обеспечивают свободную связь между кодом приложения и использованием аппаратного ускорителя (HWA).
Вступление
Модель программирования на основе директив OpenHMPP предлагает синтаксис для разгрузки вычислений на аппаратных ускорителях и для оптимизации перемещения данных в / из аппаратной памяти.
Модель основана на работах, инициированных CAPS (компилятор и архитектура для встроенных и суперскалярных процессоров) , общем проекте INRIA , CNRS , Университета Ренна 1 и INSA в Ренне.
Концепция OpenHMPP
OpenHMPP основан на концепции кодлетов, функций, которые могут удаленно выполняться на HWA.
Концепция кодлета OpenHMPP
Кодлет имеет следующие свойства:
- Это чистая функция .
- Он не содержит объявлений статических или изменчивых переменных и не ссылается на какие-либо глобальные переменные, за исключением случаев, когда они были объявлены директивой HMPP «резидентная».
- Он не содержит вызовов функций с невидимым телом (которое не может быть встроено). Это включает использование библиотек и системных функций, таких как malloc, printf, ...
- Каждый вызов функции должен ссылаться на статическую чистую функцию (без указателей на функции).
- Он не возвращает никакого значения (функция void в C или подпрограмма в Fortran ).
- Количество аргументов должно быть фиксированным (т.е. это не может быть вариативная функция, как в stdarg.h в C).
- Это не рекурсивно.
- Предполагается, что его параметры не имеют алиасинга (см. Сглаживание (вычисление) и сглаживание указателя ).
- Он не содержит директив callite (то есть RPC к другому кодлету) или других директив HMPP.
Эти свойства гарантируют, что RPC кодлета может удаленно выполняться HWA. Этот RPC и связанные с ним передачи данных могут быть асинхронными.
Codelet RPC
HMPP обеспечивает синхронный и асинхронный RPC. Реализация асинхронной работы зависит от оборудования.
Модель памяти HMPP
HMPP рассматривает два адресных пространства: одно хост-процессор и память HWA.
Концепция директив
Директивы OpenHMPP можно рассматривать как «метаинформацию», добавленную в исходный код приложения. Это безопасная метаинформация, т. Е. Они не изменяют исходное поведение кода. Они касаются удаленного выполнения (RPC) функции, а также передачи данных в / из памяти HWA.
В таблице ниже представлены директивы OpenHMPP. Директивы OpenHMPP удовлетворяют разные потребности: некоторые из них предназначены для объявлений, а другие - для управления выполнением.
Инструкции потока управления | Директивы по управлению данными | |
---|---|---|
Декларации | группа кодлетов | житель карта mapbyname |
Операционные директивы | callsite синхронизирует область | распределить расширенную загрузку выпуска, делегированное хранилище |
Понятие набора директив
Одним из фундаментальных моментов подхода 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 ] * [ & ]
Где:
: - уникальный идентификатор, называющий группу кодлетов. В тех случаях, когда в приложении не определены группы, этот ярлык можно просто пропустить. Название юридической метки должно соответствовать следующей грамматике: [az, AZ, _] [az, AZ, 0-9, _] *. Обратите внимание, что символы «<>» относятся к синтаксису и являются обязательными для такого типа меток.codelet_label
: - уникальный идентификатор кодлета. Название юридической метки должно соответствовать следующей грамматике: [az, AZ, _] [az, AZ, 0-9, _] *directive
: имя директивы;directive_parameters
: обозначает некоторые параметры, связанные с директивой. Эти параметры могут быть разных типов и указывать либо некоторые аргументы, передаваемые директиве, либо режим выполнения (например, асинхронный или синхронный);[&]
: - символ, используемый для продолжения директивы на следующей строке (то же самое для C и FORTRAN).
Параметры директивы
Параметры, связанные с директивой, могут быть разных типов. Ниже приведены параметры директивы, определенные в OpenHMPP:
version = major.minor[.micro]
: указывает версию директив HMPP, которую должен учитывать препроцессор.args[arg_items].size={dimsize[,dimsize]*}
: определяет размер нескалярного параметра (массива).args[arg_items].io=[in|out|inout]
: указывает, что указанные аргументы функции являются входными, выходными или обоими. По умолчанию вводятся неквалифицированные аргументы.cond = "expr"
: определяет условие выполнения как логическое выражение C или Fortran, которое должно быть истинным, чтобы начать выполнение группы или кодлетов.target=target_name[:target_name]*
: указывает, какие цели попытаться использовать в указанном порядке.asynchronous
: указывает, что выполнение кодлета не блокируется (по умолчанию синхронно).args[
: указывает, что указанные параметры предварительно загружены. Предварительно могут быть загружены только параметры in или inout.].advancedload=true args[arg_items].noupdate=true
: это свойство указывает, что данные уже доступны на HWA и поэтому передача не требуется. Когда это свойство установлено, передача рассматриваемого аргумента не выполняется.args[
:].addr=" "
выражение, которое дает адрес данных для загрузки.args[
: указывает, что аргумент должен быть загружен только один раз.].const=true
Директивы OpenHMPP
Директивы для объявления и выполнения кодлета
codelet
Директива объявляет вычисление дистанционно выполняется на аппаратном ускорителе. Для codelet
директивы:
- Этикетка кодлета является обязательной и должна быть уникальной в приложении.
- Метка группы не требуется, если группа не определена.
- Директива codelet вставляется непосредственно перед объявлением функции.
Синтаксис директивы:
#pragma hmpp < grp_label > codelet_label codelet [ , версия = major.minor [.micro]?]? [ , args [ arg_items ] .io = [[ in | из | inout ]] * [ , args [ arg_items ] .size = { dimsize [, dimsize] * } ] * [ , аргументы [ arg_items ] .const = true ] * [ , cond = "expr"] [ , target = target_name [: target_name ] *]
К функции можно добавить более одной директивы codelet, чтобы указать разные варианты использования или разные контексты выполнения. Однако для данной метки места вызова может быть только одна директива codelet.
В callsite
директива определяет , каким образом используют codelet в данный момент в программе.
Синтаксис директивы:
#pragma hmpp < grp_label > codelet_label callite [ , асинхронный ]? [ , args [ arg_items ] .size = { dimsize [, dimsize] * } ] * [ , args [ arg_items ] .advancedload = [[ true | ложь ]] * [ , аргументы [ arg_items ] .addr = " выражение " ] * [ , аргументы [ arg_items ] .noupdate = true ] *
Пример показан здесь:
/ * объявление кодлета * / #pragma hmpp simple1 codelet, args [outv] .io = inout, target = CUDA static void matvec ( int sn , int sm , float inv [ sm ], float inm [ sn ] [ sm ] , float * outv ) { int i , j ; для ( я = 0 ; я < sm ; я ++ ) { float temp = outv [ я ]; для ( j = 0 ; j < sn ; j ++ ) { temp + = inv [ j ] * inm [ i ] [ j ]; } outv [ i ] = temp ; } int main ( int argc , char ** argv ) { int n ; ........ / * использование кодлета * / #pragma hmpp simple1 callsite, args [outv] .size = {n} matvec ( n , m , myinc , inm , myoutv ); ........ }
В некоторых случаях требуется специальное управление данными во всем приложении (оптимизация движения данных ЦП / ГП, общие переменные ...).
group
Директива позволяет объявлять о группе codelets. Параметры, определенные в этой директиве, применяются ко всем кодлетам, принадлежащим группе. Синтаксис директивы:
#pragma hmpp < grp_label > group [ , version =. [ , target = target_name [: target_name ] *]]? [ , cond = « expr » ]?[. ]?]?
Директивы передачи данных для оптимизации коммуникационных накладных расходов
При использовании HWA основным узким местом часто является передача данных между HWA и главным процессором.
Чтобы ограничить служебные данные связи, передачи данных могут перекрываться с последовательными выполнениями одного и того же кодлета с использованием асинхронного свойства HWA.
- Распределить директиву
allocate
Директива блокирует Хва и выделяет необходимое количество памяти.
#pragma hmpp < grp_label > allocate [ , args [ arg_items ] .size = { dimsize [, dimsize] * } ] *
- директива о выпуске
В release
директиве определяет , когда , чтобы освободить HWA для группы или автономного codelet.
#pragma hmpp < grp_label > выпуск
- директива advancedload
advancedload
Директива предварительной выборки данных до удаленного выполнения codelet.
#pragma hmpp < grp_label > [codelet_label]? расширенная загрузка , args [ arg_items ] [ , args [ arg_items ] .size = { dimsize [, dimsize] * } ] * [ , аргументы [ arg_items ] .addr = " выражение " ] * [ , args [ arg_items ] .section = { [ subscript_triplet , ] + } ] * [ , асинхронный ]
- директива делегированного хранилища
delegatedstore
Директива является барьером синхронизации ждать асинхронного выполнения codelet до завершения и затем загрузить результаты.
#pragma hmpp < grp_label > [codelet_label]? делегированный магазин , args [ arg_items ] [ , args [ arg_items ] .addr = " expr " ] * [ , args [ arg_items ] .section = { [ subscript_triplet , ] + } ] *
- Асинхронные вычисления
В synchronize
директиве указаны не ждать до завершения асинхронного выполнения callsite. Для директивы synchronize метка кодлета всегда является обязательной, а метка группы требуется, если кодлет принадлежит к группе.
#pragma hmpp < grp_label > codelet_label synchronize
- Пример
В следующем примере инициализация устройства, выделение памяти и загрузка входных данных выполняются только один раз вне цикла, а не на каждой итерации цикла.
synchronize
Директива позволяет ждать асинхронного выполнения codelet завершить до запуска еще одной итерации. Наконец, delegatedstore
директива вне цикла загружает результат sgemm.
int main ( int argc , char ** argv ) { #pragma hmpp sgemm allocate, args [vin1; vin2; vout] .size = {size, size} #pragma hmpp sgemm advancedload, args [vin1; vin2; vout], args [m, n, k, alpha, beta] for ( j = 0 ; j < 2 ; j ++ ) { #pragma hmpp sgemm callite, asynchronous, args [vin1; vin2; vout] .advancedload = true, args [m, n, k, alpha, beta] .advancedload = true sgemm ( размер , размер , размер , альфа , vin1 , vin2 , beta , vout ); #pragma hmpp sgemm synchronize } #pragma hmpp sgemm delegatedstore, args [vout] #pragma hmpp sgemm release
Обмен данными между кодлетами
Эти директивы сопоставляют все аргументы, имеющие заданное имя для всей группы.
Типы и размеры всех сопоставленных аргументов должны быть идентичными.
map
Директива отображает несколько аргументов на устройстве.
#pragma hmpp < grp_label > карта, аргументы [ arg_items ]
Эта директива очень похожа на map
директиву, за исключением того, что отображаемые аргументы прямо указываются по их имени. mapbyname
Директива эквивалентна нескольких map
директив.
#pragma hmpp < grp_label > mapbyname [ , variableName] +
Глобальная переменная
resident
Директива объявляет некоторые переменные как глобальные в группе. Затем к этим переменным можно получить прямой доступ из любого кодлета, принадлежащего группе. Эта директива применяется к оператору объявления, который следует за ним в исходном коде.
Синтаксис этой директивы:
#pragma hmpp < grp_label > resident [ , args [:: var_name ] .io = [[ in | из | inout ]] * [ , Арг [:: var_name ] .size = { dimsize [, dimsize] * } ] * [ , Арг [:: var_name ] .addr = " выражение " ] * [ , Арг [:: var_name ] .const = истина ] *
Обозначение ::var_name
с префиксом ::
указывает на переменную приложения, объявленную как резидентную.
Разгон регионов
Регион - это слияние директив codelet / callite. Цель состоит в том, чтобы избежать реструктуризации кода для построения кодлета. Следовательно, все атрибуты, доступные для директив codelet
или, callsite
могут использоваться в regions
директивах.
На языке C:
#pragma hmpp [< MyGroup >] [ метка ] регион [ , args [ arg_items ] .io = [[ in | из | inout ]] * [ , cond = " expr "] < [ , аргументы [ arg_items ] .const = true ] * [ , target = target_name [ : target_name ] *] [ , args [ arg_items ] .size = { dimsize [ , dimsize] * } ] * [ , args [ arg_items ] .advancedload = [[ true | ложь ]] * [ , аргументы [ arg_items ] .addr = " выражение " ] * [ , аргументы [ arg_items ] .noupdate = true ] * [ , асинхронный ]? [ , частный = [ arg_items ] ] * {ЗАЯВЛЕНИЯ БЛОКА C }
Реализации
Открытый стандарт OpenHMPP основан на HMPP версии 2.3 (май 2009 г., предприятие CAPS).
Модель программирования на основе директив OpenHMPP реализована в:
- Компиляторы CAPS, компиляторы CAPS Entreprise для гибридных вычислений
- PathScale ENZO Compiler Suite (поддержка графических процессоров NVIDIA)
OpenHMPP используется для высокопроизводительных вычислений актеров [ кто? ] в нефти и газе, [ необходима цитата ] , [ цитата ], Производство, [ цитата ], финансы, [ цитата ], образование и исследования. [ необходима цитата ]
Смотрите также
Рекомендации
- ^ Dolbeau, Ромен; Бихан, Стефан; Боден, Франсуа (4 октября 2007 г.). HMPP: гибридная многоядерная среда параллельного программирования (PDF) . Практикум по универсальной обработке на графических процессорах . Архивировано из оригинального (PDF) 16 января 2014 года . Проверено 14 января 2014 года .
Внешние ссылки
- CAPS Entreprise SAS и PathScale, Inc будут совместно работать над превращением HMPP в новый открытый стандарт
- Как аппаратные средства будут формировать языки Дэвид Чисналл
- Ускорение кода с помощью HMPP от ICHEC (Ирландский центр высокопроизводительных вычислений)
- Опыт программирования на HMPP от IRMA (Institut de Recherche Mathématique Avancée) - примеры FORTRAN
- Порт HMPP от CEA (Commissariat à l'Energie Atomique et aux Energies Alternatives) для PRACE (Партнерство для передовых вычислений в Европе)