Параллельное программирование на языке C-DVM (1158283), страница 3
Текст из файла (страница 3)
Для того, чтобы C-DVM программа могла компилироваться и выполняться как обычная последовательная программа, копирование массивов (секций) записывается как обычный многомерный цикл. Тело цикла должно состоять из единственного оператора присваивания. Заголовки цикла должны быть записаны макрокомандами DO(v,first,last,step) или FOR(v,times). Все переменные цикла должны использоваться в индексных выражениях правой и левой части оператора присваивания, причем в одном и том же порядке. Каждое индексное выражение может содержать только одну переменную цикла и должно зависеть от нее линейно.
Для асинхронного копирования нужно:
-
объявить директивой COPY_FLAG переменную -- флаг завершения операции копирования;
-
перед циклом указать директиву COPY_START с адресом переменной-флага;
-
перед использованием присвоенных значений убедиться в завершении (дождаться завершения) операции копирования директивой COPY_WAIT с адресом той же переменной.
Пример . Асинхронное копирование.
DVM(DISTRIBUTE [BLOCK][]) float A[N][N];
DVM(ALIGN [i][j] WITH [j][i]) float B[N][N];
. . .
DVM(COPY_FLAG) void * flag;
. . .
DVM(COPY_START &flag)
FOR(i,N)
FOR(j,N)
B[i][j]=A[i][j];
. . .
DVM(COPY_WAIT &flag);
Если совмещение обменов с вычислениями не требуется, то можно несколько упростить программу, использу директиву синхронного копирования COPY.
Пример .Синхронное копирование.
DVM(COPY)
FOR(i,N)
FOR(j,N)
B[i][j]=A[i][j];
4.7Многомерные массивы
При локализации данных с помощью директивы ALIGN для многомерных массивов необходимо указывать индексы выравниваемых элементов массивов по всем измерениям.
На предмет наличия удаленных данных достаточно анализировать только распределенные измерения массивов. Локальные измерения полностью распределены на каждом процессоре и по этим измерениям не существует удаленных данных. Каждое распределенное измерение, по которому существуют удаленные данные, должно быть учтено при спецификации удаленных данных в соответствии с разделами 3.5.2 - 3.5.4.
4.8Процедуры
Вызов процедуры из параллельного цикла
Процедура, вызываемая из параллельного цикла, не должна иметь побочных эффектов и содержать обменов между процессорами (прозрачная процедура). Как следствие этого, прозрачная процедура не содержит операторов ввода-вывода и DVM-директив;
Вызов процедуры вне параллельного цикла
Если фактическим аргументом является явно распределенный массив (DISTRIBUTE или ALIGN), то он должен передаваться без изменения формы. Это означает, что фактический аргумент является ссылкой на начало массива, а соответствующий формальный аргумент имеет конфигурацию, полностью совпадающую с конфигурацией фактического аргумента.
Формальные параметры
Если фактическим параметром функции может быть распределенный массив, то формальный параметр должен быть описан следующим образом:
-
Если распределение фактического параметра известно, то директивой
DVM(*DISTRIBUTE f1…fk); -
Если известна только размерность, но не конкретное распределение, то директивой DVM(*DISTRIBUTE[*]...[*]);
-
Если фактический параметр может быть произвольным (распределенным или нераспределенным) массивом, то директивой DVM(*). Такой параметр может использоваться только в функциях fread/fwrite.
Локальные массивы
Локальные массивы могут распределяться в процедуре директивами DISTRIBUTE и ALIGN. Локальный массив может быть выровнен на формальный аргумент. Директива DISTRIBUTE распределяет локальный массив на ту подсистему процессоров, на которой была вызвана процедура (текущая подсистема).
4.9Ввод/вывод
В C-DVM, разрешены следующие операции ввода/вывода для размноженных данных:
fopen, fclose, feof, fprintf, printf, fscanf, fputc, putc, fputs, puts, fgetc, getc, fgets, gets, fflush, fseek, ftell, ferror, clearerr, perror, as well as fread, fwrite.
Эти операторы выполняются на выделенном процессоре (процессоре ввода/вывода). Выводимые значения берутся на этом процессоре, а вводимые – вводятся на нем и рассылаются на остальные процессоры.
Для распределенных данных обеспечивается только бесформатный ввод/вывод массива целиком функциями fread/fwrite.
Функции ввода/вывода не следует использовать в параллельных циклах, т.к. выводимые размноженные данные окажутся в файле (на печати) в непредсказуемом порядке, а при попытке вывода распределенных данных может произойти зависание программы.
4.10Ограничения на использование языка СИ
C-DVM предназначен для распараллеливания вычислительных программ, написанных в "фортрано-подобном" стиле. При этом на использование средств языка СИ накладываются некоторые ограничения. В первую очередь эти ограничения касаются использования указателей на распределенные массивы и их элементы. C‑DVM не запрещает использовать указатели, но некоторые операции с ними могут стать некорректными после конвертирования программы. Например:
-
идентификатор массива (или указателя на массив) становится идентификатором массива целых чисел (так называемого хендлера массива);
-
процессор содержит только локальную часть массива, поэтому относительный доступ к его элементам с помощью адресной арифметики невозможен;
-
при перераспределении массива меняется состав и расположение локальной части массива, поэтому сохраненные указатели на элементы становятся недействительными.
Второе ограничение касается типов данных: элементы распределенных массивов могут быть только скалярных типов int, long, float и double.
Некоторые описания для распараллеливания требуют выполнения определенных действий. Так например:
-
описания процессорных секций;
-
описание распределенных массивов или шаблонов с константными размерностями ("статических");
-
инициализация переменных (требуется их регистрация для отладчика).
Такого рода неявные действия для глобальных объектов выполняются в начале функции main сразу после инициализации системы поддержки. Поэтому в момент генерации main все такие объекты должны быть известны, т.е. не могут находиться в отдельно транслируемом файле или следовать за описанием функции main. Для объектов, локальных в функции или блоке, эти действия выполняются перед первым оператором блока. Кроме того заметим, что неявные действия выполняются в порядке описаний, и это накладывает определенные семантические ограничения на порядок описаний: база ALIGN должна быть описана до выравниваемого массива и т.п.
И наконец, использование препроцессора, выходящее за пределы файлов заголовков, требует осторожности по нескольким причинам. Во-первых, C-DVM компилятор работает до препроцессора. Поэтому, например, пара определений
#define begin {
#define end }
может сделать программу совершенно непонятной для компилятора. По этой же причине DVM-директивы в include-файле остаются неизвестными компилятору. Следовательно, распределенные данные должны быть описаны явно в каждом файле. Во-вторых, для работы с многомерными массивами предлагается использовать препроцессор для временного переопределения размеров массивов как констант или для определения макрокоманд, моделирующих многомерный массив на одномерном. В конвертированной программе соответствующие препроцессорные директивы должны быть удалены. Это реализовано таким образом, что все директивы препроцессора в исходном порядке помещаются в начало выходного файла. (Заметим, что для каждой вспомогательной директивы #define требуется директива #undef, отменяющая ее.)
5Компиляция, выполнение и отладка DVM-программ
5.1 Что такое DVM-программа?
Параллельная программа представляет собой обычную последовательную программу, в которую вставлены DVM-директивы, определяющие ее параллельное выполнение.
DVM-директивы записываются как параметры макроса
DVM(<directive>)
который в последовательной программе “расширяется” в пустую строку.
DVM-программа – это один или несколько файлов с исходными текстами на языке C-DVM, имеющих расширение .cdv .
5.2 Настройка DVM-системы
В рабочую директорию, в которой находится DVM-программа, необходимо переписать файл запуска dvm-команд ( dvm или dvm.bat) и файл usr.par из директории dvm_sys/user DVM-системы.
В файле запуска dvm-команд определены переменные окружения, которые могут быть изменены пользователем. Наиболее часто корректируется переменная dvmoutfile, определяющая имя файла, в который направляется вывод задачи пользователя. По умолчании вывод идет на экран.
В файле usr.par перечислены наиболее часто корректируемые параметры из базового набора параметров DVM-системы. При помощи параметра StatBufLength можно изменять размер буфера статистики. Например, если параметр IsTimeVariation задать равным единице, то буфер статистики будет использоваться также и для накопления информации о временах запуска и завершения всех коллективных операций, и поэтому его размер следует увеличить.
DVM-система имеет параметры, управляющие системой поддержки, работой динамического отладчика, сбором статистики. В документах [3,4] можно найти описание всех параметров DVM-системы и указания по составлению своих наборов параметров и файлов запуска dvm-команд, содержащих различные значения переменных окружения.
5.3 Методика отладки DVM-программ
Под отладкой DVM-программ подразумеваются два различных вида деятельности :
-
функциональная отладка, целью которой является достижение правильности функционального выполнения программы;
-
отладка эффективности, целью которой является достижение требуемого уровня эффективности параллельного выполнения программы.
Во время отладки и выполнения DVM-программ могут появиться сообщения об ошибках системы поддержки. Вид этих сообщений и описание возможных причин их появления приведены в приложении 4.
5.3.1Функциональная отладка программы
Функциональную отладку программ рекомендуется проводить на тестовых данных в следующей последовательности шагов.
-
Последовательное выполнение и отладка средствами стандартного компилятора с языка Си
DVM-директивы прозрачны для стандартных компиляторов, поэтому DVM-программа обрабатывается ими как обычная последовательная программа Это позволяет отлаживать ее как обычную последовательную программу (в режиме игнорирования DVM-директив) с использованием привычных средств отладки.
-
Компиляция. Получение готовой программы
Получение готовой программы (выполняемого файла) осуществляется в три этапа:
-
конвертация C-DVM программы в C-программу с получением одноименного файла (файлов) с расширением .c;
-
компиляция полученного на предыдущем этапе файла (файлов) стандартным компилятором с языка С;
-
связывание полученного объектного модуля (модулей) с библиотеками программ, используемых пользователем (если есть), и с библиотекой Lib-DVM – системой поддержки выполнения параллельных DVM-программ.
Команда конвертации и компиляции С-DVM-программы имеет вид:
dvm c <имя_DVM-программы>
где:
dvm | | префикс (имя файла запуска DVM-команд); |
<имя_DVM-программы> | | имя файла с исходным текстом программы без расширения. Поиск файла производится только в текущей директории. Предполагается, что он является правильным с точки зрения синтаксиса C и транслируется стандартным C-компилятором (конвертор не делает стандартной проверки синтаксиса и семантики C); |
Результат работы: файлы <имя_DVM-программы>.с и готовая программа (выполняемый файл <имя_DVM-программы>) в текущей директории. Если конвертор обнаружил ошибки, то файл <имя_DVM-программы>.с и соответственно готовая программа не создаются. Сообщения об ошибках записываются в файл cdvm_msg. Список диагностических сообщений приведен в приложении
4.3.1.3 Динамический контроль DVM-указаний
Динамический контроль DVM-указаний позволяет проверить корректность распараллеливания программы посредством DVM-указаний, и основан на моделировании параллельного выполнения DVM-программы во время ее последовательного выполнения на одном процессоре.