Тип строки:
type=ordered
Передается имя файла:
file = <имя файла>
Номер строки, в которой стоит директива ORDERED:
line1=<номер строки>
Номер строки, в которой стоит директива END_ORDERED:
line2=<номер строки>
void DBG_OrderedEvent(long *StaticContextHandle, long *ThreadID)
Функция вызывается после директивы ORDERED
void DBG_AfterOrdered(long *StaticContextHandle, long *ThreadID)
Функция вызывается после директивы END_ORDERED.
2.8 Классы переменных
2.8.2 Директива THREADPRIVATE
!$omp threadprivate(list)
void DBG_ThreadPrivateEvent(long *StaticContextHandle, long *ThreadID)
Вызов данной функции добавляется сразу после раздела описаний (первый исполняемый оператор в инструментируемой функции).
Дескриптор StaticContextHandle указывает на контекстную строку следующего формата:
Тип строки:
type=threadprivate
Передается имя файла:
file = <имя файла>
Номер строки, в которой стоит директива THREADPRIVATE:
line1=<номер строки>
Дескриптор StaticContextHandle также содержит информацию о переменных - параметрах директивы THREADPRIVATE:
name1=<список имен переменных/common-блоков через запятую>
3. Инструментация операторов Fortran 77.
3.1 Раздел описаний
3.1.1 Описание переменных
Каждая скалярная переменная, описанная в программе/функции, регистрируется при помощи следующего вызова:
void DBG_RegVar(long *StaticContextHandle, long *ThreadID, void*VarHandle)
Вызов данной функции добавляется сразу после раздела описаний.
VarHandle - адрес скалярной переменной.
StaticContextHandle указывает на контекстную строку следующего формата:
Тип строки:
type=var_name
Передается имя файла, в котором эта переменная описана:
file = <имя файла>
Номер строки в файле:
line1=<номер строки>
Имя переменной:
name1=<имя переменной>
Тип переменной:
vtype=<тип>,
где тип может принимать следующие значения (число, соответствующее типу, используемому в системе DVM):
0– для rt_CHAR
1– для rt_INT
2- для rt_LONG
3- для rt_FLOAT
4- для rt_DOUBLE
5- для rt_FLOAT_COMPLEX
6- для rt_DOUBLE_COMPLEX
Если переменная была проинициализирована в операторе DATA:
isindata=1
Если переменная входит в COMMON-блок:
isincommon=1
Если для переменной был указан аттрибут SAVE:
isinsave=1
Каждый массив, описанный в программе/функции, регистрируется при помощи следующего вызова:
void DBG_RegArr(long *StaticContextHandle, long *ThreadID, long *ArrSize, void* ArrHandle)
Вызов данной функции добавляется сразу после раздела описаний.
ArrSize - массив размеров массива по каждому измерению.
ArrHandle – адрес первого элемента массива.
Дескриптор StaticContextHandle указывает на контекстную строку следующего формата:
Тип строки:
type=arr_name
Передается имя файла, в котором эта переменная описана:
file = <имя файла>
Номер строки в файле:
line1=<номер строки>
Имя массива:
name1=<имя массива>
Тип элементов массива:
vtype=<тип>,
где тип может принимать следующие значения (число, соответствующее типу, используемому в системе DVM):
0– для rt_CHAR
1– для rt_INT
2- для rt_LONG
3- для rt_FLOAT
4- для rt_DOUBLE
5- для rt_FLOAT_COMPLEX
6- для rt_DOUBLE_COMPLEX
Размерность регистрируемого массива:
rank=<размерность регистрируемого массива>
Если массив (или его элементы) был проинициализирован в операторе DATA:
isindata=1
Если массив входит в COMMON-блок:
isincommon=1
Если для массива был указан аттрибут SAVE:
isinsave=1
Замечание. Вызовов для отмены регистрации переменных и массивов не предусмотрено. Предполагается, что у отладчика есть вся необходимая информация, чтобы он был в состоянии выполнить такую дерегистрацию автоматически по выходу из процедуры.
3.1.2 Описание COMMON-блоков
Каждое описание COMMON-блока в программе/функции, регистрируется при помощи следующего вызова:
void DBG_RegCommon(long *StaticContextHandle, long *ThreadID)
Вызов данной функции добавляется сразу после раздела описаний.
Дескриптор StaticContextHandle указывает на контекстную строку следующего формата:
Тип строки:
type=common _name
Передается имя файла, в котором эта блок описан:
file =<имя файла>
Номер строки в файле:
line1=<номер строки>
Имя COMMON-блока:
name1=<имя COMMON-блока>
Компоненты COMMON-блока:
name2=<список переменных через запятую>
3.2 Выполняемые операторы
3.2.1 Чтение/запись переменных
Для каждого выполняемого оператора фиксируются все записи/чтения переменных:
void DBG_ReadVar(long* file_line_info, long *ThreadID, void*pAddr, long *var_name)
void DBG_ReadArr(long* file_line_info, long *ThreadID, void*pAddr, long *var_name, void*pBase)
Замечание. Использование переменных в качестве параметров функций/процедур, инструментируется отдельно (см. раздел 3.2.3)
Функции сообщают отладчику о чтении переменной (DBG_ReadVar), элемента массива (DBG_ReadArr).
file_line_info – дескриптор с информацией о текущей строке и имени файла:
Тип строки:
type=file_name
Передается имя файла:
file =<имя файла>
Номер строки в файле:
line1=<номер строки>
pAddr – адрес считываемой переменной или элемента массива.
var_name – дескриптор, указанный при регистрации переменной/массива (параметр StaticContextHandle в DBG_RegVar/ DBG_RegArr).
pBase – адрес первого элемента массива.
Функции DBG_Write*Begin отмечают начало модификации переменной или элемента массива.
void DBG_WriteVarBegin(long *file_line_info, long *ThreadID, void*pAddr, long* var_name)
void DBG_WriteArrBegin(long *file_line_info, long *ThreadID, void*pAddr, long* var_name, void*pBase)
Их параметры аналогичны параметрам функций DBG_Read*. Вызовы этих функций должны вставляться до присвоения переменной значения и до вычисления присваиваемого выражения. Эти функции должны быть парными с DBG_WriteEnd().
void DBG_WriteEnd(long* file_line_info, long *ThreadID, void*pAddr)
Функция отмечает завершение вычисления выражения и присвоение переменной или элементу массива нового значения. Функция должна вызываться после присвоения переменной или элементу массива нового значения и должна быть парной с одним их вызовов DBG_Write*Begin().
3.2.2 Последовательные циклы
void DBG_BegSL(long *StaticContextHandle, long *ThreadID, long *Init, long *Last, long *Step)
Функция сообщает отладчику о начале последовательного цикла, вызывается перед входом в цикл.
Init, Last, Step – адреса номеров первой и последней итераций и шага цикла соответственно.
Остальная информация о цикле передается при помощи контекстной строки (StaticContextHandle).
Тип строки:
type=seqloop
Передается имя файла:
file = <имя файла>
Номер строки, в которой начинается цикл:
line1=<номер строки>
Номер строки, в которой цикл заканчивается:
line2=<номер строки>
void DBG_SIter(long *StaticContextHandle, long *ThreadID, long *Index)
Функция сообщает отладчику о начале очередной итерации последовательного цикла. Функция вызывается в самом начале выполнения каждой итерации, после модификации итерационной переменной.
Index – адрес номера текущей итерации.
void DBG_EndSL(long *StaticContextHandle, long *ThreadID)
Функция сообщает отладчику о конце последовательного цикла. Функция вызывается после завершения последней итерации последовательного цикла.
3.2.3 Функции
void DBG_BeforeFuncCall(long *StaticContextHandle, long *ThreadID)
Добавляется перед вызовом функции. Информация о вызове передается при помощи дескриптора StaticContextHandle:
Тип строки:
type=func_call
Передается имя файла:
file = <имя файла>
Номер строки, в которой вызывается функция:
line1=<номер строки>
Название функции:
name1=<название функции>
Количество параметров функции:
rank=<количество параметров>
Инструментатор не занимается межпроцедурным анализом программы. В большинстве случаев, у инструментатора нет информации о том, как в процедуре использовались переменные, указанные в качестве параметров (на чтение, запись или чтение/запись). Поэтому вызовы DBG_Read* и DBG_Write*, используемые для инструментации чтения и записи в переменные для функций не применимы.
Для фактических параметров функций используются:
void DBG_FuncParVar(long *StaticContextHandle, long *ThreadID, int *Position, void*pAddr, long *var_name, int *IsRead)
void DBG_FuncParArr(long *StaticContextHandle, long *ThreadID, int *Position, void*pAddr, long *var_name, void*pBase, int *IsRead)
Функции сообщают отладчику об использовании переменной (DBG_FuncParVar) или элемента массива (DBG_FuncParArr) в качестве параметра при вызове функции.
pAddr – адрес используемой переменной или элемента массива.
Position – номер параметра (от 1 до rank)
var_name – дескриптор, указанный при регистрации переменной/массива (параметр StaticContextHandle в DBG_RegVar/ DBG_RegArr).
pBase – адрес первого элемента массива.
Признак IsRead определяет тип использования переменной. Если в качестве фактического параметра указано выражение, по виду которого инструментатор в состоянии определить: что переменная читалась при вычислении данного выражения, то для этой переменной значение IsRead устанавливается равным 1. Во всех остальных случаях, IsRead устанавливается равным 0.
Например, для вызова:
CALL F(X+10, A(I)-10, B(I))
Обращение к переменной X, элементу массиву A(I) – будет иметь признак IsRead==1.
Для обращения к элементу B(I) – IsRead==0
Для всех параметров функции соответствующая инструментация об использовании переменных добавляется до и после вызова функции.
void DBG_AfterFuncCall(long *StaticContextHandle, long *ThreadID)
Добавляется после выхода из функции. При инструментации программы для одного вызова процедуры параметр StaticContextHandle в вызовах DBG_BeforeFuncCall, DBG_AfterFuncCall, а также для DBG_FuncPar* - совпадает.
Функции DBG_BeforeFuncCall, DBG_AfterFuncCall позволяют отладчику отследить все входы/выходы в процедуры. В том числе тогда, когда исходный код процедуры не доступен (например, используется библиотечная функция).
Для пользовательских функций возможна более подробная инструментация:
void DBG_FuncBegin(long *StaticContextHandle, long *ThreadID)
Функция DBG_FuncBegin вызывается в самом начале инструментируемой пользовательской функции и сообщает отладчику о входе в функцию пользователя, информация о которой содержится в дескрипторе StaticContextHandle:
Тип строки:
type=function
Передается имя файла:
file = <имя файла>
Номер строки, в которой начинается функция:
line1=<номер строки>
Номер строки, в которой функция заканчивается:
line2=<номер строки>
Название функции:
name1=<название функции>
Количество параметров функции
rank=<количество параметров>
void DBG_FuncEnd(long *StaticContextHandle, long *ThreadID)
Функция сообщает отладчику о выходе из функции пользователя, информация о которой содержится в дескрипторе StaticContextHandle. Функция DBG_FuncEnd вызывается перед выходом из инструментируемой пользовательской функции (в том числе и перед досрочным выходом).
void DBG_RegParVar(long *StaticContextHandle, long *ThreadID, void*VarHandle, int *Position)
void DBG_RegParArr(long *StaticContextHandle, long *ThreadID, long *ArrSize, void*ArrHandle, int *Position)
Данные функции используются для регистрации формальных параметров процедуры. Каждый формальный параметр регистрируется аналогично обычным переменным. Параметр Position задает номер параметра процедуры. Такая регистрация может быть полезной, особенно тогда, когда отличаются размерности фактического и формального параметров (например, в вызывающей процедуре описан многомерный массив, который внутри процедуры используется как одномерный).
4. Управление инструментацией
4.1 Управление инструментацией опциями инструментатора
Если пользователь не указал ни одной из нижеперечисленных опций, то в программе не должно быть никаких вызовов отладчика.
-d1 | инструментировать только то, что явно указано пользователем с помощью директив управления инструментацией из исходного кода |
-d2 | инструментировать основные конструкции (их список приведен далее) и функции |
-d3 | инструментировать все конструкции, функции, записи в переменные |
-d4 | инструментировать все конструкции, функции, чтения и записи в переменные |
-dif | инструментировать OpenMP и последовательные циклы с условными операторами |
-dnodir | этот параметр указывает на то, что необходимо проигнорировать все директивы управления инструментацией в исходном коде |
Все параметры условно делятся на три класса: (–d1 - –d4), (–dif) и (–dnodir). Допускается указание не более одного параметра каждого класса в командной строке конвертера (в противном случае – ошибка). Всегда должен быть указан один из параметров первого класса, если указан хотя бы один параметр других классов (иначе - ошибка). Если не указан параметр –dif, инструментация производится без управления граничными итерациями. По умолчанию, если не указан параметр –dnodir директивы исходного кода учитываются всегда (они имеют больший приоритет, чем уровень инструментации указанный с помощью директив –d1 - –d4, –dif). Совместное использование параметров –dnodir и –d1 запрещено (должна быть выдана ошибка).
4.2 Управление инструментацией из программы пользователя
4.2.1 Управление уровнем подробности:
!$DVM DBG level
…
!$DVM DBGEND
Level может принимать значения OFF, MINIMAL, MODIFY, FULL. Указание уровня подробности инструментации с помощью директив имеет более высокий приоритет, чем опции командной строки инструментатора. Например, если в программе есть директивы, повышающие уровень подробности на определенных интервалах, то эти интервалы должны инструментироваться указанным уровнем подробности.
4.2.3 Управление инструментацией с условными операторами:
!$DVM DBG IF [ON|OFF]
…
!$DVM DBG END
Указанная директива позволяет управлять инструментацией с условными операторами и имеет больший приоритет, чем соответствующая опция командной строки.
Вложенные директивы управления инструментацией допускаются, однако, директива!$DVM DBG END всегда соответствует самой последней открывающей директиве!$DVM DBG XXX. После директивы!$DVM DBG END осуществляется возврат к тому уровню подробности, который был до открывающей директивы!$DVM DBG ХХХ.
4.3 Инструментация с условными операторами
В программах, состоящих из циклов обработки массивов, наиболее вероятными местами совершения и проявления ошибок являются граничные итерации циклов. Эту особенность можно использовать, если накапливать трассировку только на граничных итерациях циклов. В параллельных программах имеет смысл трассировать граничные итерации циклов, выполняемых на каждом процессоре (каждой нитью).
Однако даже при анализе только граничных итераций возможно существенное замедление выполнения программы, которое может быть вызвано тем, что на внутренних итерациях циклов функции отладчика все равно вызываются, даже если они ничего не делают. Предлагается использовать следующий подход, позволяющий не вызывать функции отладчика на внутренних итерациях циклов: окружить вызовы функций отладчика условными операторами. В качестве условия в этих операторах использовать специальную переменную, значение которой будет «истина» на граничных итерациях циклов и «ложь» - на внутренних.
Если задан режим инструментации с условными операторами, то вместо функций:
void DBG_SIter(long *StaticContextHandle, long *ThreadID, long *Index)
void DBG_OMPIter(long *StaticContextHandle, long *ThreadID, long *Index),
используемых при инструментации очередной итерации последовательного или OpenMP - цикла. Первым оператором цикла добавляются вызовы:
void DBG_SIfIter(long *StaticContextHandle, long *ThreadID, long *Index, long *IfVar)
void DBG_OMPIfIter(long *StaticContextHandle, long *ThreadID, long *Index, long *IfVar)
Данные функции отличаются только наличием параметра IfVar – адреса приватной для каждой нити переменной, которая определяет обращаться или нет на данной итерации к отладчику. Отладчик, используя информацию о цикле, задаваемую через StaticContextHandle, и текущее значение счетчика цикла устанавливает значение переменной IfVar.
Значение переменной IfVar используется далее в цикле:
DO I = 1,100
call DBG_SIfIter(dbgid1, i, dbgvar00)
IF (dbgvar00 .eq. 1) THEN
код с вызовами отладчика
ENDIF
…
ENDDO
Замечание. Подряд стоящие обращения к отладчику объединяются в один оператор IF/ENDIF.
4.4 Соответствие между уровнями подробности инструментации и инструментируемыми событиями
Ниже приведена таблица соответствия между вызовом API отладчика и уровнем инструментации программы (заданным либо параметром командной строки, либо директивами исходного кода). Звездочка в ячейке (стр, стб) означает, что при уровне подробности стб должны генерироваться вызовы функции отладчика стр.
-d0 (OFF) | -d2 (MINIMAL) | -d3 (MODIFY) | -d4 (FULL) | |
DBG_Init | * | * | * | |
DBG_Finalize | * | * | * | |
DBG_BegSL | * | * | * | |
DBG_Siter | * | * | * | |
DBG_EndSL | * | * | * | |
DBG_BeforeOMPLoop | * | * | * | |
DBG_OMPIter | * | * | * | |
DBG_AfterOMPLoop | * | * | * | |
DBG_FuncBegin | * | * | * | |
DBG_FuncEnd | * | * | * | |
DBG_BeforeFuncCall | * | * | * | |
DBG_AfterFuncCall | * | * | * | |
DBG_ReadVar | * | |||
DBG_ReadArr | * | |||
DBG_WriteVarBegin | * | * | ||
DBG_WriteArrBegin | * | * | ||
DBG_WriteEnd | * | * | ||
DBG_FuncParVar | * | * | ||
DBG_FuncParArr | * | * | ||
DBG_RegVar | * | * | ||
DBG_UnregVar | * | * | ||
DBG_RegArr | * | * | ||
DBG_UnregArr | * | * | ||
DBG_RegCommon | * | * | ||
DBG_ThreadPrivateEvent | * | * | ||
DBG_RegParVar | * | * | ||
DBG_UnregParVar | * | * | ||
DBG_RegParArr | * | * | ||
DBG_UnregParArr | * | * | ||
DBG_BeforeParallel | * | * | * | |
DBG_AfterParallel | * | * | * | |
DBG_ParallelEvent | * | * | * | |
DBG_BeforeWorkshare | * | * | * | |
DBG_AfterWorkshare | * | * | * | |
DBG_BeforeSections | * | * | * | |
DBG_AfterSections | * | * | * | |
DBG_SectionEvent | * | * | * | |
DBG_BeforeSingle | * | * | * | |
DBG_AfterSingle | * | * | * | |
DBG_BeforeCritical | * | * | * | |
DBG_CriticalEvent | * | * | * | |
DBG_AfterCritical | * | * | * | |
DBG_MasterBegin | * | * | * | |
DBG_MasterEnd | * | * | * | |
DBG_BeforeOrdered | * | * | * | |
DBG_OrderedEvent | * | * | * | |
DBG_AfterOrdered | * | * | * | |
DBG_BeforeBarrier | * | * | * | |
DBG_AfterBarrier | * | * | * | |
DBG_FlushEvent | * | * |
5. Недостатки
Недостатки предлагаемого интерфейса:
1) Никак не инструментируются операторы ввода-вывода.
2) Не инструментируются никакие вызовы библиотеки системы поддержки OPENMP (LOCKS, SET_NUM_THREADS …), которые могут существенно влиять на выполнение программы.
6. Литература
[spec25.pdf] OpenMP Application Program Interface. Version 2.5
http://www. openmp. org/drupal/mp-documents/spec25.pdf
[EWOMP02-POMP. pdf] A Performance Monitoring Interface for OpenMP/ http://www. research. /actc/projects/pdf/EWOMP02-POMP. pdf
[lacsi01.pdf] Design and Prototype of a Performance Tool Interface for OpenMP/
http://www. fz-juelich. de/zam/kojak/opari/docs/lacsi01.pdf
[fdvmUGr. html] http://www. *****/dvm/dvmhtm1107/rus/usr/fdvm/fdvmUGr. html
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 |


