DVM отладчик - оглавление Часть 1 (1 - 4) Часть 2
(5 - 6.4)
Часть 3 (6.5) Часть 4 (7)
дата документа: февраль. 2000 - дата последнего обновления 22.05.01 -

5 Метод контроля DVM-указаний

Все данные, которые могут использоваться в DVM-программе, разделяются на следующие классы:

Исходя из этих классов данных, строятся алгоритмы проверки.

5.1 Контроль инициализации переменных и элементов массивов

Данный контроль осуществляется для всех классов переменных. Каждой переменной соответствует флаг ее инициализации (массиву соответствует массив флагов). Данный флаг устанавливается при записи нового значения в переменную или элемент массива. При чтении переменной или элемента массива проверяется состояние данного флага, и если он не установлен, то диагностируется ошибка использования неинициализированных данных.

5.2 Контроль доступа к элементам распределенного массива

Проверка зависимости цикла по данным осуществляется только при обращении к элементам распределенного массива. Витки параллельного цикла могут зависеть друг от друга из-за использования в них редукционных переменных, однако, в этом случае зависимость по данным не препятствует параллельному выполнению цикла и должна быть объявлена программистом при спецификации параллельного цикла. При отсутствии такого объявления, переменная будет рассматриваться как приватная, и будет зафиксирована ошибка использования приватной переменной (см. ниже).

Каждому элементу распределенного массива при его создании ставится в соответствие структура, описывающая тип обращения к данному элементу (чтение или запись) и номер последнего витка цикла или последней параллельной задачи, в где данное обращение произошло. При вхождении в параллельный цикл или область параллельных задач, все эти структуры инициализируются начальным статусом, означающим, что к элементу массива еще не было обращений. Когда элемент используется внутри параллельной конструкции, для него запоминается номер витка или задачи и тип доступа. Если один и тот же элемент модифицируется в одном витке и используется в другом, то диагностируется ошибка зависимости параллельной конструкции по данным.

Замечание. Зависимость по данным может возникать и в случае использования размноженных переменных. Если эти переменные являются редукционными, то такая зависимость не препятствует параллельному выполнению цикла, однако, она должна быть специфицирована программистом при объявлении параллельного цикла. Если программа не имеет такой спецификации, то переменная будет трактоваться как приватная, и будет выявлена ошибка некорректного использования приватной переменной.

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

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

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

Состояние “обновление не выполнялось” устанавливается при модификации любого экспортируемого элемента распределенного массива. Это обеспечивает контроль некорректного доступа к теневым элементам до начала выполнения следующей операции обновления теневых граней.

5.3 Контроль приватных и неизменяемых переменных

Класс обычной (не редукционной) размноженной переменной определяется при первом обращении к ней внутри параллельной конструкции. Если это обращение на чтение, то переменная считается неизменяемой. Если же первое обращение произошло для записи в переменную, то она считается приватной.

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

При использовании неизменяемых переменных проверяется тип обращения к ним. При попытке модификации таких переменных диагностируется ошибка.

5.4 Контроль редукционных переменных

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

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

Замечание. Неверная спецификация редукционной операции (например, задание MIN вместо MAX) не обнаруживается при данном методе, но будет обнаружена при использовании метода сравнения результатов выполнения.

5.5 Контроль использования буфера удаленных элементов

Буфер удаленных элементов используется для предварительной загрузки для каждого процессора требуемых ему нелокальных элементов. Для него используются все те же проверки, которые осуществляются для распределенных массивов, за исключением следующих случаев:

5.6 Реализация системы динамического контроля DVM-указаний

Подсистема динамического контроля включает в себя следующие компоненты:

5.6.1 Режим работы динамического контроля с таблицей переменных

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

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

При обращении к какой-либо переменной, по ее адресу осуществляется поиск соответствующей записи в таблице переменных. Здесь возможны три варианта:

  1. Переменная в таблице не содержится. В этом случае создается новая запись и заносится в таблицу. Для этой записи запоминается текущий уровень исполнения программы и определяется класс использования переменной в зависимости от контекста обращения к ней. Сформированная запись возвращается как результат поиска.
  2. Переменная в таблице содержится, но ее уровень исполнения, содержащийся в записи, не соответствует текущему. Для этого случая также создается новая запись и заносится в таблицу со значением текущего уровня исполнения. Сформированная запись возвращается как результат поиска. В записи запоминается ссылка на описание переменной для предыдущего уровня исполнения. Класс переменной, в этом случае, определяется не только контекстом обращения к переменной, но и классом этой переменной на предыдущем уровне исполнения. При удалении записи переменной из таблицы (например, в связи с завершением параллельной конструкции), производится обновление необходимой информации для соответствующей записи предыдущего уровня.
  3. Переменная в таблице содержится, и ее уровень исполнения соответствует текущему. В этом случае найденная запись возвращается как результат поиска.

Записи в таблицу переменных также заносятся и при обращении к некоторым функциям библиотеки поддержки Lib-DVM. Например, при объявлении распределенного массива или при занесении переменной в редукционную группу создаются записи в таблице с соответствующими классами использования.

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

5.6.2 Основные функции модуля динамического контроля

Прототипы функций динамического контроля следующие:

void dyn_Init(void)

Функция инициализирует все структур, необходимых для работы модуля динамического контроля.

void dyn_Done(void)

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

void dyn_LevelDone(void)

Функция вызывается при завершении текущей параллельной конструкции.

void dyn_RemoveAll(void)

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

VarInfo* dyn_GetVarInfo( void* pAddr )
     
pAddr адрес переменной.

Функция осуществляет поиск описания переменной по ее адресу. Если переменная не зарегистрирована, то возвращается NULL.

VarInfo *dyn_CheckVar( char *Operand, void *addr, SysHandle *Handle,
                                            byte isWrt )
     
Operand имя переменной;
addr адрес переменной;
Handle дескриптор распределенного DVM-массива. Равен NULL для все остальных типов переменных;
isWrt тип обращения к переменной.

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

VarInfo *dyn_CheckValidVar( VarInfo *Current, void *addr, SysHandle *Handle,
                                                     byte isWrt )
     
Current указатель на текущее описание переменной по указанному адресу;
addr адрес переменной;
Handle дескриптор распределенного массива;
isWrt тип обращения к переменной.

Функция производит проверку описания переменной на соответствие текущему уровню исполнения. Если Current не соответствует текущему уровню, то создается новое описание переменной, которое возвращается как результат функции. Иначе возвращается указатель Current.

void dyn_CheckReadOnlyVar(char* szOperand, VarInfo *pVar, byte bIsWrt,
                                                    long lLineIndex)
     
szOperand имя переменной;
pVar указатель на описание переменной;
bIsWrt тип обращения к переменной;
lLineIndex абсолютный индекс элемента массива. Равен -1 для скалярных переменных.

Функция осуществляет проверку обращений к неизменяемым переменным.

void dyn_CheckPrivateVar(char* szOperand, VarInfo* pVar, byte bIsWrt,
                                               long lLineIndex)
     
szOperand имя переменной;
pVar указатель на описание переменной;
bIsWrt тип обращения к переменной;
lLineIndex абсолютный индекс элемента массива. Равен -1 для скалярных переменных.

Функция осуществляет проверку обращений к приватным переменным.

void dyn_CheckReductVar(char* szOperand, VarInfo *pVar, byte bIsWrt,
                                               long lLineIndex)
     
szOperand имя переменной;
pVar указатель на описание переменной;
bIsWrt тип обращения к переменной;
lLineIndex абсолютный индекс элемента массива. Равен -1 для скалярных переменных.

Функция осуществляет проверку обращений к редукционным переменным.

void dyn_CheckDisArrayVar(char* szOperand, VarInfo *pVar, byte bIsWrt,
                                                  long lLineIndex)
     
szOperand имя переменной;
pVar указатель на описание переменной;
bIsWrt тип обращения к переменной;
lLineIndex абсолютный индекс элемента массива.

Функция осуществляет проверку обращений к распределенным DVM-массивам.

VarInfo *dyn_DefineVar( byte type, byte Stat, void *addr, SysHandle *Handle,
                                            void *Info,
                                            PFN_VARTABLE_ELEMDESTRUCTOR pfnDestructor)
     
type класс переменной;
Stat статическая переменная или нет (определяет время жизни переменной);
addr адрес переменной;
Handle дескриптор распределенного DVM-массива. Равен NULL для всех остальных типов переменных;
Info дополнительная информация о переменной;
pfnDestructor деструктор переменной. Вызывается при ее удалении из таблицы переменных.

Общая функция регистрации новой переменной.

VarInfo *dyn_DefineReduct( byte Stat, void *addr )
     
Stat статическая переменная или нет (определяет время жизни переменной);
addr адрес переменной.

Функция регистрации редукционной переменной.

VarInfo *dyn_DefineDisArray( SysHandle *Handle, byte Stat, DISARR_INFO *Info )
     
Handle дескриптор распределенного DVM-массива;
Stat статическая переменная или нет (определяет время жизни переменной);
Info дополнительное описание распределенного массива.

Функция регистрации распределенного массива.

VarInfo *dyn_DefinePrivate( void *addr, byte Stat )
     
addr адрес переменной;
Stat статическая переменная или нет (определяет время жизни переменной);

Функция регистрации переменной приватного класса.

VarInfo *dyn_DefineReadOnly( void *addr, void *Info )
     
addr адрес переменной;
Info дополнительное описание переменной.

Функция регистрации неизменяемой переменной.

VarInfo *dyn_DefineRemoteBufferArray( SysHandle *SrcHandle,
                                                                        SysHandle *DstHandle, long *Index )
     
SrcHandle исходный распределенный DVM-массив;
DstHandle создаваемый буфер удаленного доступа;
Index массив индексов элементов, для которых создается буфер.

Функция регистрации буфера удаленного доступа как распределенного массива для нескольких элементов DVM-массива.

VarInfo *dyn_DefineRemoteBufferScalar( SysHandle *SrcHandle, void *RmtBuff,
                                                                         long *Index )
     
SrcHandle исходный распределенный DVM-массив;
RmtBuff адрес переменной, выступающей в качестве буфер удаленного доступа;
Index массив индексов элемента, для которого создается буфер.

Функция регистрации буфера удаленного доступа как скалярной переменной для элемента DVM-массива.

void dyn_DestructReduct( VarInfo *Var )
     
Var указатель на описание переменной.

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

void dyn_DestructPrivate( VarInfo *Var )
     
Var указатель на описание переменной.

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

void dyn_DestructReadOnly( VarInfo *Var )
     
Var указатель на описание переменной.

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

void dyn_DestructDisArray( VarInfo *Var )
     
Var указатель на описание переменной.

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

void dyn_RemoveVar( void *addr )
     
addr адрес переменной.

Функция удаления описания переменной с указанным адресом для текущего уровня выполнения.

void dyn_InitializeSet( VarInfo *Var, size_t LI )
     
Var указатель на описание переменной;
LI абсолютный индекс элемента массива. Равен -1 для скалярных переменных.

Функция устанавливает флаг инициализации переменной или элемента массива.

void dyn_InitializeClear( VarInfo *Var )
     
Var указатель на описание переменной.

Функция сбрасывает флаг инициализации переменной или всех элементов массива.

int dyn_InitializeCheck( VarInfo *Var, size_t LI )
     
Var указатель на описание переменной;
LI абсолютный индекс элемента массива. Равен -1 для скалярных переменных.

Функция возвращает значение флага инициализации переменной или элемента массива. Возвращает 1 при установленном флаге и 0 – иначе.

void dyn_DisArrAcross(s_DISARRAY *Arr)
     
Arr указатель на описание распределенного массива системы поддержки.

Функция выставляет флаг использования распределенного DVM-массива в параллельном цикле с зависимостью по данным типа ACROSS. Для данного массива в пределах текущего параллельного цикла не будут производиться проверки на зависимость по данным.

void dyn_DisArrCheckBounds( char *Operand, VarInfo *Var, size_t LI, byte isWrt,
                                                     long Iter )
     
Operand имя переменной;
Var указатель на описание переменной;
     
LI абсолютный индекс элемента массива;
isWrt тип доступа к элементу массива;
Iter абсолютный номер текущей итерации параллельного цикла.

Функция вычисляет локальную часть массива, принадлежащую текущей абстрактной машине, и проверяет принадлежность элемента массива этой локальной части или ее границам. Функция также проверяет корректность использования границ массива.

void dyn_DisArrCheckSequential(char* szOperand, VarInfo* pVar, byte bIsWrt,
                                                          long lLineIndex)
     
szOperand имя переменной;
pVar указатель на описание переменной;
bIsWrt тип доступа к элементу массива;
lLineIndex абсолютный индекс элемента массива.

Функция проверяет корректность доступа к элементу распределенного DVM-массива в последовательной части программы.

void dyn_DisArrCheckDataDepends( char *Operand, VarInfo *Var, size_t LI,
                                                                byte isWrt, long Iter )
     
Operand имя переменной;
Var указатель на описание переменной;
LI абсолютный индекс элемента массива;
isWrt 1, если элемент используется для записи. Иначе – 0;
Iter абсолютный номер текущей итерации параллельного цикла.

Функция проверяет зависимость цикла по данным при использовании элементов распределенного массива.

byte dyn_DisArrCheckLimits( char *Operand, long LI, DISARR_INFO *Info )
     
Operand имя переменной;
LI абсолютный индекс элемента массива;
Info описание распределенного массива.

Функция осуществляет проверку на выход за пределы распределенного массива. Возвращает 1, если элемент с абсолютным индексом LI находится в пределах границ локального блока массива.

byte dyn_GetLocalBlock(s_BLOCK *DABlock, s_DISARRAY *DA,
                                            s_PARLOOP *PL)
     
DABlock указатель на переменную, в которую будет записан вычисленный блок;
DA указатель на описание распределенного массива системы поддержки;
PL указатель на описания параллельного цикла системы поддержки.

Функция вычисляет блок распределенного массива, обращения к элементам которого допустимы внутри текущей итерации параллельного цикла. Возвращает 0 в случае успешного вычисления блока.

void dyn_DisArrDefineShadow(s_DISARRAY* pArr,
                                                     s_BOUNDGROUP* pBndGroup,
                                                     s_SHDWIDTH* pRtsShadow)
     
pArr указатель на описание распределенного DVM-массива системы поддержки;
pBndGroup указатель на описание группы границ системы поддержки;
pRtsShadow указатель на описание теневых граней массива.

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

void dyn_DisArrCompleteShadows(s_DISARRAY* pArr,
                                                            s_BOUNDGROUP* pBndGroup)
     
pArr указатель на описание распределенного DVM-массива системы поддержки;
pBndGroup указатель на описание группы границ системы поддержки.

Функция выставляет флаг завершения обмена границ распределенного массива, входящих в указанную группу.

void dyn_DisArrClearShadows(DISARR_INFO* pInfo)
     
pInfo описание распределенного массива.

Функция удаляет все записи об обмене границ для указанного распределенного массива. Вызывается после модификации экспортируемых элементов массива.

int dyn_FindShadowIndex(s_BLOCK* pBlock, long* sI, DISARR_INFO* pInfo)
     
pBlock описание локального блока массива;
sI массив индексов элемента распределенного DVM-массива;
pInfo описание распределенного массива.

Функция перебирает все описания теневых граней, связанные с распределенным массивом, и возвращает номер описания гранией, в пределах которых находится указанный элемент массива. Функция возвращает -1, если элемент массива не принадлежит ни одной из теневых граней массива.

5.6.3 Параметры системы динамического контроля

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

Параметры задаются в специальных файлах, располагающихся в специальной директории DVM-системы. Параметры имеют следующий вид:

<Имя параметра>=<Значение>.

Динамическим контролем используются следующие значения:

EnableDynControl – динамический контроль выполняется, если параметр больше 0, и динамический контроль запрещен при значении 0.

DebugOptions.ErrorFileвыводятся сообщения об – имя файла с диагностикой об ошибках. В данный файл ошибках, найденных при динамическом контроле, если значение параметра DebugOptions.ErrorToScreen равно 0. Если попытки открытия файла окажутся неуспешными, то диагностика будет выводиться на экран.

DebugOptions.HashIndexSize – размер индекса хеш-таблицы для таблицы переменных.

DebugOptions.HashTableSize – размер массивов хеш-таблиц.

DebugOptions.VarTableSize – размер таблиц переменных.

DebugOptions.ErrorToScreen – если значение не равно 0, то вся диагностика динамического контроля выводится на экран.

DebugOptions.PrintStatistic – если значение параметра не равно 0, то по окончании работы программы печатается статистика работы с таблицей переменных. Статистика выводится в файл DebugOptions.ErrorFile или на экран в зависимости от значения параметра DebugOptions.ErrorToScreen.

DebugOptions.AppendErrorFile – определяет режим записи в файл диагностики при его использовании. Если значение равно 0, то при каждом запуске задачи содержимое этого файла стирается.

DebugOptions.MaxErrors – определяет максимальное число ошибок, после которого динамический контроль будет отключен.

DebugOptions.CheckVarInitialization – если значение не равно 0, то разрешена проверка инициализации скалярных переменных.

DebugOptions.CheckVarReadOnly – если значение не равно 0, то разрешена проверка использования переменным с доступом только на чтение.

DebugOptions.CheckReductionAccess – если значение не равно 0, то разрешена проверка использования редукционных переменных.

DebugOptions.CheckDisArrInitialization – если значение не равно 0, то разрешена проверка инициализации элементов распределенных массивов.

DebugOptions.CheckDisArrLimits – если значение не равно 0, то разрешена проверка обращений к элементам распределенного массива за пределами его границ.

DebugOptions.CheckDisArrEdgeExchange – если значение не равно 0, то разрешена проверка обмена теневых граней распределенных массивов.

DebugOptions.CheckDisArrSequentialAccess – если значение не равно 0, то разрешена проверка использования элементов распределенных массивов в последовательной части программы.

DebugOptions.CheckDisArrLocalElm – если значение не равно 0, то разрешена проверка на принадлежность элемена распределенного массива его локальной части.

DebugOptions.CheckDataDependence – если значение не равно 0, то разрешена проверка на зависимость параллельных циклов по данным.

DebugOptions.CheckRemoteBufferAccess – если значение не равно 0, то разрешена проверка использования буферов удаленного доступа.

HashMethod – определяет алгоритм вычисления хеш-значения. 0 – используется функция StandartHashCalc, 1 – используется функция OffsetHashCalc.

HashOffsetValue – величина смещения для алгоритма OffsetHashCalc. Допускаются значения от 0 до 16.

6 Метод сравнения результатов выполнения

6.1 Накопление трассировки

При накоплении результатов вычислений в файл записывается следующая информация:

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

Поскольку метод сравнения результатов требует значительных накладных расходов, то предусмотрены средства управления степенью подробности накопления результатов выполнения.

Степень подробности накопления определяется содержимым специального файла – конфигурационного файла трассировки. Этот файл содержит описание всех исполняемых конструкций программы (области задач и циклы). Если данный файл не существует, то можно с помощью параметров задать его создание.

Для того чтобы сократить объем накапливаемой информации, для каждого цикла, для каждой области задач и для всей программы в целом можно задать следующие уровни накопления:

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

6.2 Сравнение результатов

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

При последующем выполнении программы, трассируемые события сравниваются с эталонными.

При этом, учитываются следующие особенности выполнения программы в параллельном режиме:

6.3 Контроль редукционных операций

Накопление редукционных переменных осуществляется специальным образом. Значения редукционных переменных во время их вычисления в параллельном цикле не сравниваются с эталонными. Сравниваются только результаты окончательного вычисления редукции.

Для контроля правильности спецификации редукционной операции, вычисление редукционной операции производится двумя различными способами. Первый способ – это стандартный метод вычисления редукции. Сначала на каждом процессоре выполняются отображенные на него витки параллельного цикла или параллельные задачи, в которых в соответствии с заданным программистом алгоритмом будет вычислен частичный результат редукции. Конечный результат редукционной операции вычисляется библиотекой Lib-DVM путем объединения всех частичных результатов в соответствии с описанной программистом редукционной операцией. Если программа выполняется последовательно (или параллельно, но на одном процессоре), то редукционная операция целиком будет вычислена в соответствии с заданным программистом алгоритмом.

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

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

6.4 Форматы входных и выходных файлов

6.4.1 Конфигурационный файл трассировки

Этот файл служит не только для задания степени подробности трассировки для каждой конструкции программы, но и для выдачи программисту объемов трассировки при заданных уровнях ее подробности. Запуская программу в режиме формирования конфигурационного файла (без реального накопления трассировки) и корректируя каждый раз получаемый файл, программист имеет возможность добиться наиболее подходящей степени подробности трассировки.

Как уже было сказано, существуют следующие уровни подробности трассировки:

Уровень подробности трассировки всей программы задается при запуске программы в файле параметров. Уровень подробности трассировки для каждой конструкции программы задается в конфигурационном файле. Если уровень подробности для конструкции не задан, то он наследуется от объемлющей конструкции. Если объемлющей конструкции не существует, то принимается уровень всей программы.

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

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

Комментарии в конфигурационном файле начинаются с символа ‘#’. Вся строка после этого символа игнорируется.

Структура конфигурационного файла следующая:

# Trace size = <объем всей трассировки>
# String count = <число строк всей трассировки>

<SL | PL | TR> <номер конструкции> (<номер объемлющей конструкции>) [<ранг цикла>] {<имя файла>, <номер строки>} = <NONE | MINIMAL | MODIFY | FULL>, (<измерение>:<первый виток>, < последний виток>, <шаг >), …

# Trace size = <объем трассировки конструкции>
# String count = <число строк трассировки конструкции>
# Count of traced iterations = <число трассируемых витков или задач>

EL: <номер конструкции>

………

<SL | PL | TR> <номер конструкции> (<номер объемлющей конструкции>) [<ранг цикла>] {<имя файла>, <номер строки>} = <NONE | MINIMAL | MODIFY | FULL>, (<измерение>:<первый виток>, < последний виток>, <шаг >), …

# Trace size = <объем трассировки конструкции>
# String count = <число строк трассировки конструкции>
# Count of traced iterations = <число трассируемых витков или задач>

EL: <номер конструкции>

Все параметры исполняющихся конструкций задаются после символа ‘=’. Запись SL соответствует обычному последовательному циклу, запись LP соответствует параллельному циклу а запись TR – области параллельных задач.

Если множество трассируемых витков не задано, то будут трассироваться все витки или задачи. Множество витков задается следующим образом:

(<измерение> : [<первый виток>] , [<последний виток>] , [<шаг>])

<измерение> – измерение цикла (начинается с 0) для которого задается диапазон. Области задач и последовательные циклы всегда имеют только одно измерение с номером 0. Данный параметр обязателен.

<первый виток> – номер витка, начиная с которого будут трассироваться витки. По умолчанию – с первого витка.

<последний виток> – номер витка, по который будут трассироваться витки. По умолчанию – по последний виток.

<шаг> – шаг, с которым будут трассироваться витки. По умолчанию полагается единице.

Примеры задания множества витков:

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

6.4.2 Файл трассировки

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

Формат заголовка идентичен формату конфигурационного файла и имеет следующий вид:

MODE = <NONE | MINIMAL | MODIFY | FULL>, [EMPTYITER]
# Begin trace header. Don't modify these records
<SL | PL | TR> <номер конструкции> (<номер объемлющей конструкции>) [<ранг цикла>] {<имя файла>, <номер строки>} = <NONE | MINIMAL | MODIFY | FULL>, (<измерение>:<первый виток>, < последний виток>, <шаг >), …
EL: <номер конструкции>

<SL | PL | TR> <номер конструкции> (<номер объемлющей конструкции>) [<ранг цикла>] {<имя файла>, <номер строки>} = <NONE | MINIMAL | MODIFY | FULL>, (<измерение>:<первый виток>, < последний виток>, <шаг >), …
EL: <номер конструкции>

END_HEADER
# End trace header

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

После заголовка, в файле трассировки идут записи следующих типов и форматов:


DVM отладчик - оглавление Часть 1 (1 - 4) Часть 2
(5 - 6.4)
Часть 3 (6.5) Часть 4 (7)