[improvement] Concept of sequential regions #51
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Механизм последовательных регионов
Существующий механизм областей распараллеливания
В системе SAPFOR области распараллеливания задаются при помощи директивы
PARALLEL_REG <name>:Они позволяют сузить распараллеливание до отдельных фрагментов, так как часто распараллелить программу полностью сложно или невозможно.
Больше про области распараллеливания можно прочитать в магистерской диссертации Яшина Сергея Владимировича (прикреплённый файл).
Механизм последовательных регионов
Регионы последовательного выполнения планируется использовать для того, чтобы исключить фрагмент(ы) программы из распараллеливания. На данный момент в сапфоре такого функционала нет, в некоторых случаях нужного поведения можно добиться путём покрытия всей программы за исключением избранных фрагментов параллельными регионами.
Идея состоит в том, чтобы ввести новую директиву (или новую форму директивы
PARALLEL_REG) с помощью которой можно помечать фрагменты, внутри которых системе не следует проводить распараллеливание.Я больше склоняюсь к введению новой директивы, вот причины:
PARALLEL_REGвсё же обозначает параллельный регионтекущая форма
PARALLEL_REGтребует наличия поля<name>которое теряет смысл при задании последовательного регионасейчас запрещены вложенные директивы
PARALLEL_REGДалее будем считать, что для создания последовательных регионов будет использоваться (несуществующая) директива
SEQUENTIAL_REG.Далее приведу несколько примеров, чтобы было понятно, как и в каких случаях можно будет использовать эту директиву:
Пример 1
В программе нет параллельных регионов, поэтому распараллеливаться будет всё, кроме второго цикла из-за директивы.
Пример 2
В программе есть один параллельный регион на первом цикле, поэтому распараллеливаться будет только он, директива
SEQUENTIAL_REGтут допустима, но не имеет эффекта.Пример 3
Директива
SEQUENTIAL_REGможет быть вложена в директивуPARALLEL_REG. В таком случае опять первый цикл должен будет распараллелен, второй - нет.Пример 4
Директива
SEQUENTIAL_REGможет быть вложена в директивуPARALLEL_REG, при этом они могут находится на разных уровнях вложенности (но соответствующие директивыSEQUENTIAL_REG,END SEQUENTIAL_REGдолжны находиться на одном уровне). Такая конструкция означает, что внушний цикл может быть распараллелен, а внутренний нет (SAPFOR должен сгенерировать директивуPARALLEL (i), но неPARALLEL (i, j)). Аналогично директиваSEQUENTIAL_REGможет быть вложена вPARALLEL_REGнеявно, то есть находится в теле функции, вызываемой явно или неявно из фрагмента директивыPARALLEL_REG.Устранение конфликтов
Для устранения конфликтов областей распараллеливания сейчас, в основном, производится две операции: создание массивов-копий и функций-копий. Чтобы сохранить корректность распараллеливания, нужно посмотреть на эти операции с точки зрения добавляемых областей последовательного выполнения.
Если говорить обобщённо, то возможны следующие случаи при определении области последовательного выполнения:
Она не может разорвать параллельный регион (например, если она стоит внутри распараллеливаемого цикла как в примере 4). Тогда она никак не влияет на копирование массивов и функций.
Она разрывает регион. Тогда на образовавшихся границах нужно добавить ещё по копированию (в обе стороны) каждого массива, использующегося в выделенной области. Если в этой области есть функции которые больше в параллельной области не используются, их можно не копировать; никакие вызовы функций в такой выделенной области менять не нужно (должны вызываться оригинальные функции).
Пример 5 (разрыв параллельного региона)
Распараллеливание на общую память
В случае распараллеливания на общую память ситуация становится только легче, так как копирование массивов их копий можно опустить (так как массивы не распределяются).
Но это относится скорее не к теме областей последоательного выполнения, а к проходу устранения конфликтов, точнее к эффективной поддержке в нём режима распараллеливания на общую память.
В целом связка проходов устрение конфликтов (для случая с распределением) + распараллеливание на общую память работает корректно.
Примерная реализация
На этапе парсинга директив
PARALLEL_REGбудут также парсится директивыSEQUENTIAL_REG. Сейчас параллельные регионы отражены в системе при помощи структурыParallelRegionкоторая в свою очередь хранит множество фрагментов, составляющих регион, отражённых структурамиParallelRegionLines.Планируется завести аналогичное множество структур
ParallelRegionLines(на самом деле структуруParallelRegionLinesможно переименовать вCodeFragment, так как ничего касательно параллельности там не содержится, только фрагмент из АСТ программы) и использовать его как множество фрагментов, которые следует исключить из распараллеливания. Заполняться эти множество будут в момент парсинга директивSEQUENTIAL_REGдля параллельных регионов (на самом деле одного региона), в которые вложен текущий фрагмент. При распараллеливании будет учитываться тот факт, что внутри этих фрагментов распараллеливание вести не следует.UPD: добавил мысли по поводу устранения конфликтов областей
Не хочу переходить отсюда в трекер, потому что там не распознаётся Markdown, туда просто продублирую. Файл с диссертацией можно найти там же.
Я не уверен, что стоит думать сразу над несколькими проблемами, может быть стоит хотя бы на уровне ТЗ разобраться с областями?
Пункт устранения конфликтов мне кажется не до конца продумано, так как здесь описываются ситуации с распараллеливанием на общую память. В такой постановке по идее надо знать, какой режим распараллеливания будет использоваться и уже в зависимости от него, либо создавать копии, либо нет.
Из-за того, что ранее был только один режим, требовались разрежения конфликтов и создание массивов копий, так как без этого просто невозможно распараллелить программу. Теперь мы приходим к тому, что у нас есть два режима и в каждом из режимов нужно действовать по разному. И возникает вопрос, как нам теперь контролировать этот момент при расстановке областей и работы с ними?
UPD: обновил параграф с устранением конфликтов, немного написал о том, как жто соотносится с общей памятью
Решили сделать это проще и только для операторов ввода-вывода