44300

Повышение эффективности отладки DVM

Дипломная

Информатика, кибернетика и программирование

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

Русский

2013-11-11

431 KB

1 чел.

40

Московский Государственный Университет им. М. В. Ломоносова

Факультет Вычислительной Математики и Кибернетики

Кафедра Системного Программирования

ДИПЛОМНАЯ РАБОТА

Повышение эффективности отладки DVMпрограмм

Выполнил:

Кудрявцев Максим Владимирович

группа 527

Научный руководитель:

профессор, д. ф.-м. наук

Крюков В. А.

Москва

2003

Содержание

[1] Повышение эффективности отладки DVMпрограмм

[1.1] Содержание

[1.2]
Введение

[1.3]
Глава 1. Параллельные программы и их отладка

[1.3.1] Модели параллельного программирования

[1.3.2] Отладка параллельных программ

[1.4]
Глава 2. Отладка в системе DVM

[1.4.1] Основные положения

[1.4.2] Накопление трассировки

[1.4.3] Сравнение результатов вычислений

[1.4.4] Файл трассировки

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

[1.4.6]
Постановка задачи

[1.5]
Глава 3. Новые возможности управления размером трассировки

[1.5.1] Нумерация параллельных конструкций

[1.5.2] Задание точек начала и окончания подробной трассировки

[1.5.3] Задание ограничений на трассировку итераций

[1.6]
Глава 4. Уровень подробности контрольных сумм

[1.6.1] Накопление контрольных сумм

[1.6.2] Конфигурационный файл. Файл трассировки.

[1.6.3] Сравнение контрольных сумм

[1.6.4] Реализация уровня подробности контрольных сумм

[1.7]
Глава 5. Сохранение элементов массива в заданный файл

[1.8]
Глава 6. Оценка эффективности предложенных возможностей

[1.9]
Заключение

[1.10]
Литература

[1.11]
Приложение 1. Сообщения об ошибках отладчика системы DVM (добавленные)

[1.12]
Приложение 2. Параметры отладчика системы DVM (добавленные)


Введение

Система DVM [], разработанная в Институте прикладной математики им. М. В. Келдыша РАН в 1998 году предназначена для разработки мобильных и эффективных программ для ЭВМ различной архитектуры.

Существующие средства отладки системы DVM сильно замедляют выполнение программы и используют большое количество памяти для накопления трассировки. С этим можно бороться, используя высокопроизводительную ЭВМ с большим количеством как оперативной, так и внешней памяти, либо можно предложить пользователю запускать его программу на модельных данных. У последнего варианта есть недостатки. Например, могут возникнуть сложности с подбором модельных данных (программа «чужая», для подбора модельных данных в ней надо разбираться) или программа с модельными данными может давать правильные результаты (ошибка может не проявляться).

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

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


Глава 1. Параллельные программы и их отладка

Модели параллельного программирования

Растущие потребности человека заставляют его искать способы увеличения производительности выполнения компьютерных программ. Что обычно делают люди для того, чтобы увеличить производительность своей работы? Есть несколько способов []: работать интенсивнее, работать сообразительнее и попросить чьей-либо помощи. Можно привести аналогию по отношению к вычислительной технике: чтобы повысить производительность выполнения компьютерных программ можно использовать более мощное аппаратное обеспечение, более эффективные алгоритмы (как на уровне программного обеспечения, так и аппаратного), либо использовать возможности параллельной обработки информации.

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

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

В настоящее время существуют следующие модели программирования []:

  •  Модель передачи сообщений. В этой модели программа представляет собой совокупность процессов, каждый из которых имеет своё адресное пространство. Причем эти процессы взаимодействуют и синхронизируются только через передачу сообщений. Для этой модели разработан стандарт MPI (Message Passing Interface []).
  •  Модель неструктурированных нитей. Программа представляется как совокупность нитей (threads), способных выполняться параллельно и имеющих общее адресное пространство. Имеющиеся средства синхронизации нитей позволяют организовывать доступ к общим ресурсам. Многие среды программирования поддерживают эту модель: Win32 threads, POSIX threads, Java threads.
  •  Модель параллелизма по данным. Основным её представителем является язык HPF []. В этой модели  программист самостоятельно распределяет данные последовательной программы по процессорам. Далее последовательная программа преобразуется компилятором в параллельную, выполняющуюся либо в модели передачи сообщений, либо в модели с общей памятью. При этом каждый процессор производит вычисления только над теми данными, которые на него распределены.
  •  Модель параллелизма по управлению. Эта модель возникла в применении к мультипроцессорам. Вместо терминов нитей предлагалось использовать специальные конструкции – параллельные циклы и параллельные секции. Создание, уничтожение нитей, распределение на них витков параллельных циклов или параллельных секций – всё это брал на себя компилятор. Стандартом для этой модели сейчас является интерфейс OpenMP [].
  •  Гибридная модель параллелизма по управлению с передачей сообщений. Программа представляет собой систему взаимодействующих MPI – процессов, каждый из которых программируется на OpenMP.
  •  Модель параллелизма по данным и управлениюDVM (Distributed Virtual Machine, Distributed Virtual Memory) [].

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

Эта модель лежит в основе языков параллельного программирования системы DVM – Фортран-DVM и Си-DVM. Программа на этих языках, помимо описания алгоритма обычными средствами языков Фортран 77 или Си, содержит правила параллельного выполнения этого алгоритма. Программисту предоставляются следующие возможности спецификации параллельного выполнения программы:

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

Модель выполнения DVM-программы можно упрощенно описать следующим образом [].

Параллельная программа на исходном языке Фортран-DVM (или Си-DVM) при помощи специального компилятора превращается в программу на  языке Фортран 77 (или Си), содержащую вызовы функций системы поддержки Lib-DVM, и выполняющуюся в соответствии с моделью SPMD (одна программа – много данных) на каждом выделенном задаче процессоре.

В момент запуска программы существует единственная её ветвь (поток управления), которая начинает свое выполнение с первого оператора программы сразу на всех процессорах многопроцессорной системы.

Многопроцессорной системой (или системой процессоров)  называется та машина, которая предоставляется программе пользователя аппаратурой и базовым системным программным обеспечением. Для распределённой ЭВМ примером такой машины может служить MPI-машина. В этом случае, многопроцессорная система это группа MPI-процессов, которые создаются при запуске параллельной программы на выполнение. Число процессоров многопроцессорной системы и её представление в виде многомерной решетки задаётся в командной строке при запуске программы.

Все объявленные в программе переменные (за исключением специально указанных "распределённых" массивов) размножаются по всем процессорам.

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

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

Отладка параллельных программ

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

Усложнение коснулось и отладки программ1, так по сравнению с отладкой последовательных программ

  •  растёт сложность программирования и, следовательно, вероятность совершения ошибок и сложность отладки;
  •  возможны специфичные для параллельных программ ошибки (взаимная блокировка (deadlock), условия гонок (race condition), и т. д.), которые вызывают недетерминированное поведение программы и сложны для обнаружения.

Отладка параллельных программ осложняется (в большей степени, чем отладка последовательных программ) так называемым эффектом вмешательства (probe effect): отлаживаемая программа может вести себя по-разному при её запуске с отладочным средством и без него. Таким образом, отладочное средство может маскировать некоторые ошибки или, наоборот, способствовать их проявлению.

Поначалу ситуация с отладчиками параллельных программ была примерно такой же, как с первыми языками программирования – каждый владелец параллельной вычислительной системы имел свои собственные средства отладки. В 1997 году усилия по стандартизации командного интерфейса интерактивного отладчика параллельных программ возглавил форум по отладке высокопроизводительного программного обеспечения – HPDF [] (High Performance Debugging Forum) консорциума по параллельным инструментальным средствам Ptools (The Parallel Tools Consortium). В результате в 1998 году была создана версия 1 стандарта командного интерфейса интерактивного отладчика, однако, до сих пор не известно ни одной реализации отладчика, удовлетворяющей этому стандарту. Казалось бы, почему? По-видимому, стандарт был создан слишком поздно. Ко времени его написания уже существовало несколько широко используемых средств отладки параллельных программ.

Отладка параллельных программ достойна отдельного рассмотрения (вне контекста отладки последовательных программ), по крайней мере, по двум причинам:

  •  существуют ошибки свойственные исключительно параллельным программам (это уже упомянутые взаимные блокировки (deadlocks), условия гонок (race conditions), и т. д.);
  •  некоторые параллельные программы вообще не могут быть запущены на последовательной ЭВМ, поскольку необходимые данные не могут уместиться в оперативной памяти последовательной машины (а модельные данные подобрать очень сложно). Параллельные программы могут выполняться настолько долго на последовательной ЭВМ, что никто не сможет дождаться их результатов.

В настоящее время можно выявить следующие методики отладки параллельных программ:

  •  Статический анализ. Для отладки не используются процессы выполнения программ. Средство отладки производит анализ исходного кода программы и выносит заключение об обнаруженных ошибках;
  •  Анализ отладочной информации после завершения выполнения программы (post-mortem analysis). Во время выполнения сохраняется отладочная информация, анализ которой производится уже после завершения выполнения отлаживаемой программы. Использование данной методики позволяет минимизировать эффект вмешательства отладчика в программы для систем с распределённой памятью;
  •  Интерактивная отладка. Обычный способ отладки последовательных программ – установка точек останова и контроля данных, выполнение программы (процесса(-ов), нити(-ей)) до одной из этих точек, анализ состояния программы, и т. д.
  •  Динамический контроль. Средство отладки вмешивается в выполнение программы, производит анализ выполнения заданных условий. В случае обнаружения ошибки выдаётся соответствующее сообщение.
  •  Методика «записать и воспроизвести» (record & replay). Данная методика предназначена для обнаружения трудновоспроизводимых ошибок. Отладка программы по этой методике состоит из
    •  выполнения отлаживаемой программы со сбором информации, необходимой для детерминированного воспроизведения её выполнения;
    •  повторных детерминированных запусков этой программы с использованием собранной информации и возможностей интерактивной отладки (точек останова, точек контроля данных, и т. п.).
  •  Сравнительная отладка. При отладке программ по этой методике производится сравнение данных отлаживаемой программы с данными программы, производящей правильные вычисления. Выполнение  программ и сравнение данных может быть реализовано по-разному:
    •  сравнение данных может производиться в процессе выполнения обоих программ;
    •  при выполнении одной программы её данные сравниваются с данными трассировки, полученной при выполнении другой;
    •  сравниваются данные трассировок обоих программ.

Область применения сравнительной отладки ограничивается переписыванием (переход к новой версии программы, например, от последовательной к параллельной или добавление или изменение программного кода) и переносом программ на другую программно-аппаратную платформу.

Существующие реализации методики сравнительной отладки в области параллельных вычислений – сравнительный отладчик Guard [], исследовательский проект NASA Ames (прототипная реализация системы сравнительной отладки для программ, полученных при помощи средств автоматизированного распараллеливания (computer-aided tools) []) и отладчик системы DVM [], который кроме методики сравнительной отладки реализует методику динамического контроля.


Глава 2. Отладка в системе DVM

Основные положения

Отладчик системы DVM (входит в состав системы времени выполнения) предназначен для функциональной отладки параллельных программ, написанных на языках системы DVM - Fortran-DVM и C-DVM [, ].

Предлагается следующая методика отладки DVM-программ [, , ]:

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

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

Можно выделить следующие классы ошибок [, , ]:

  1.  Синтаксические ошибки в DVM-указаниях (неправильная запись оператора, отсутствие скобки и т.д.), а также нарушение статической семантики.
  2.  Неправильная последовательность выполнения DVM-указаний или неправильные параметры DVM-указаний.
  3.  Ошибки, приводящие к неправильному выполнению вычислений (например, некорректность DVM-указаний или ошибки программы, не проявляющиеся при ее последовательном выполнении).
  4.  Ошибки, не проявляющиеся при последовательном выполнении программы, но приводящие к аварийному завершению параллельного выполнения программы (авосты, зацикливания, зависания).

Синтаксические ошибки в программе выявляются при компиляции.

Ошибки второго класса обнаруживаются библиотекой Lib-DVM при параллельном выполнении программы: функции библиотеки проверяют корректность порядка выполнения DVM-указаний и передаваемых параметров.

Ошибки третьего класса должны выявляться динамическим отладчиком при:

  •  запуске DVM-программы на одном процессоре в режиме динамического контроля;
  •  запуске DVM-программы на одном или нескольких процессорах в режиме сравнения результатов ее параллельного выполнения с эталонными результатами, полученными при ее последовательном выполнении.

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

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

  •  начало последовательного или параллельного цикла;
  •  завершение последовательного или параллельного цикла;
  •  начало нового витка цикла;
  •  обращение к переменной на чтение;
  •  перед обращением к переменной на запись;
  •  после обращения к переменной на запись.

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

В рамках методик динамического контроля и сравнительной отладки отладчик системы DVM предоставляет возможности:

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

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

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

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

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

  1.  Программу можно разбить на фрагменты и при ее компиляции для каждого фрагмента указать, в каких точках должны быть вставлены обращения к отладчику (обращения к любым переменным, модификация любых переменных, обращения к распределенным массивам, модификация распределенных массивов).
  2.  При запуске программы с помощью специального параметра можно задать один из следующих возможных уровней подробности трассировки:
  •  отсутствие трассировки (уровень NONE);
  •  трассировка редукционных операций, начала и завершения циклов или областей задач и начала витков или задач (уровень MINIMAL);
  •  предыдущий уровень, плюс трассировка модификаций переменных и результатов вычисления редукции (уровень MODIFY);
  •  трассировка всех событий (уровень FULL).
  1.  При запуске программы с помощью специального конфигурационного файла можно задать уровень подробности трассировки для каждого ее цикла или области задач. Там же можно ограничить множество трассируемых витков.

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

Использование возможности (2) без комбинации с другими возможностями представляется нам не очень перспективным, поскольку  вероятность обнаружения ошибки с использованием уровня подробности трассировки MINIMAL достаточно мала, а размер трассировки и время выполнения программы на уровнях MODIFY и FULL высоки.

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

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

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

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

Сравнение результатов вычислений

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

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

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

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

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

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

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 определяет уровень подробности трассировки всей программы и режим накопления пустых витков. Все остальные строки определяют параметры для конкретных конструкций программы, семантику этих конструкций см. ниже.

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

  •  Чтение переменной:
    RD: [<тип переменной>] <имя переменной> = <значение>; {<файл>, <строка>}
  •  Начало оператора присваивания нового значения переменной:
    BW: [<тип переменной>] <имя переменной> ; {<файл>, <строка>}
  •  Запись нового значения переменной:
    AW: [<тип переменной>] < имя переменной > = <значение>; {<файл>, <строка>}
  •  Чтение редукционной переменной:
    RV_RD: [<тип переменной >] < имя переменной > = < значение >; {< файл>, <строка >}
  •  Начало оператора присваивания нового значения редукционной переменной:
    RV_BW: [<тип переменной >] < имя переменной >; {< файл>, <строка >}
  •  Запись нового значения редукционной переменной:
    RV_AW: [<тип переменной>] <имя переменной> = <значение>; {<файл>, <строка>}
  •  Результат вычисления редукции:
    RV: [<тип переменной >] <значение>; {< файл>, <строка >}
  •  Завершение блока собственных вычислений в последовательной части программы:
    SKP: {< файл>, <строка >}
  •  Начало параллельного цикла:
    PL: <номер конструкции> (<номер объемлющей конструкции>) [<ранг цикла>] ; {<файл>, <строка>}
  •  Начало последовательного цикла:
    SL: <номер конструкции> (<номер объемлющей конструкции>) [<ранг цикла (всегда равен единице)>] ; {<файл>, <строка>}
  •  Начало области параллельных задач:
    TR: <номер конструкции> (<номер объемлющей конструкции>) [<ранг области (всегда равен единице)>] ; {<файл>, <строка>}
  •  Начало витка или параллельной задачи:
    IT: <абсолютный индекс витка (вычисляется из значений всех индексных переменных цикла) или номер задачи>, (<значение индексной переменной 1>,< значение индексной переменной 2>,…).
  •  Завершение параллельного или последовательного цикла или области задач:
    EL: <номер конструкции>; {<файл>, <строка>}

Эти записи определяют динамическую структуру программы, то есть последовательность операторов в процессе выполнения программы.

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

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

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

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

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

Комментарии в конфигурационном файле начинаются с символа ‘#’. Вся строка после этого символа игнорируется. Формат конфигурационного файла аналогичен формату заголовка файла трассировки. Некоторые подробности здесь опущены, см. [, , ].


Постановка задачи

С учётом выделенных замечаний для повышения эффективности отладки DVM-программ предлагается:

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


Глава 3. Новые возможности управления размером трассировки

Нумерация параллельных конструкций

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

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

Нумеровать удобно именно параллельные конструкции (параллельные циклы и области задач), поскольку имеется:

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

Вернёмся к вопросу об инвариантности нумерации для разных запусков программы. Нумерация будет инвариантна, если при любом запуске программы последовательность параллельных конструкций строго фиксирована (отсутствуют условные операторы, которые при каких-либо условиях могут приводить к выполнению разных параллельных конструкций). Например, не должно быть конструкции такого вида, даже если параллельные циклы 1 и 2 синтаксически совпадают:

if (NUMBER_OF_PROCESSORS() == 1)

{

. . .

<параллельный цикл 1>

 . . .

}

else

{

. . .

<параллельный цикл 2>

. . .

}

Поскольку нумерацию предполагается использовать для указания точек и диапазонов, то имеет смысл отличать начало конструкции от её конца. Предлагается следующий алгоритм нумерации. Начнём нумерацию с единицы. Параллельные конструкции, не находящиеся внутри области задач нумеруются по порядку. Начало конструкции и её конец различаются указанием символов «B» и «E» соответственно после номера конструкции с точкой. Параллельные циклы находящиеся внутри подзадачи области задач будем нумеровать следующим образом:

<номер области задач>.<номер подзадачи>.<номер параллельного цикла внутри подзадачи (нумерация начинается с единицы)>.<B или E>

Заметим, что вложенные друг в друга параллельные циклы недопустимы.

Опишем изменения синтаксиса записей конструкций трассировки:

  •  Начало параллельного цикла:

PL: <номер цикла> (<номер родительской конструкции или пусто>) [<размерность цикла>] = <уровень трассировки: FULL, MODIFY, MINIMAL, NONE>, (<диапазон трассируемых итераций (может отсутствовать)>); {<имя файла>, <номер строки>}, <динамический номер конструкции>

  •  Начало области задач:

TR: <номер области> (<номер родительской конструкции или пусто>) [<размерность области>] = <уровень трассировки: FULL, MODIFY, MINIMAL, NONE>, (<диапазон трассируемых задач>); {<имя файла>, <номер строки>}, <динамический номер конструкции>

  •  Завершение параллельного или последовательного цикла или области задач:

EL: <номер конструкции>; {<имя файла>, <номер строки>}, <динамический номер конструкции (для посл. циклов отсутствует)>

Примеры нумерации:

  •  параллельный цикл:

PL: 2() [2]; {"a.cdv", 31}, 6.B

...

EL: 2; {"a.cdv", 31}, 6.E

  •  область задач:

TR: 5(10) [1]; {"b.cdv", 95}, 256.B

...

EL: 5; {"b.cdv", 95}, 256.E

  •  параллельный цикл внутри области задач:

TR: 5(10) [1]; {"c.cdv", 95}, 256.B

...

PL: 13(5) [2]; {"c.cdv", 40}, 256.3.4.B

 ...

EL: 13; {"c.cdv", 40}, 256.3.4.E

...

EL: 5; {"c.cdv", 95}, 256.E

Особенности реализации

Библиотека времени выполнения системы DVM написана на языке программирования Си, поэтому наши модификации библиотеки тоже производятся на этом языка.

Для хранения номеров используется тип NUMBER:

typedef struct tag_NUMBER

{

   struct level

   {

       long    val; /* number */

       char    ref; /* 'B' - loop begin, 'E' - loop end */

   };

   /* main level */

   struct level main;

   /* nested level */

   struct level nested;

   /* selector: which level to choose, 0 - main, 1 - nested */

   byte selector;

   /* iteration if we are in task region */

   long iter;

}

NUMBER;

Значение 1 поля selector означает, что данная структура является номером параллельного цикла внутри области задач. Поле main используется для хранения информации о номере области задач, поле nested – для хранения информации о номере вложенного в область задач параллельного цикла. В противном случае (значение поля selector 0) структура нумерует параллельный цикл, номер которого находится в поле main.

Функции для работы с номерами:

char* to_string(NUMBER *num, char *buffer)

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

byte parse_number(char *str, NUMBER *num)

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

int num_cmp(NUMBER *num1, NUMBER *num2)

Функция производит сравнение двух номеров. Возвращаемые значения:

0: номера равны
1: num1 > num2
-1: num1 < num2
-2: номера не сравнимы, например, 1.0.1.E и 1.1.1.E

void num_init(NUMBER *num)

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

void ploop_beg(NUMBER *num)

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

void ploop_end(NUMBER *num)

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

void tr_beg(NUMBER *num)

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

void tr_it(NUMBER *num, long iter)

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

void tr_end(NUMBER *num)

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

Также введён макрос DBG_ASSERT(file, line, expr), который в случае, когда выражение expr ложно выдаёт сообщение об ошибке и принудительно завершает выполнение программы. Этот макрос необходим для проверки корректности передаваемых в перечисленные функции параметров. Если, скажем, после конструкции начала параллельного цикла будет трассироваться конструкция начала области задач, то произведётся вызов указанного макроса, который выведет сообщение об ошибке с указанием строки и имени файла, в которых это произошло. В случае необходимости отключения таких проверок достаточно переопределить этот макрос на макрос-пустышку.

Задание точек начала и окончания подробной трассировки

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

Точки начала и окончания подробной трассировки задаются при помощи параметров TraceOptions.StartPoint и TraceOptions.FinishPoint соответственно. Требуемый уровень подробности устанавливается при помощи параметра TraceOptions.TraceLevel файла параметров, при этом учитываются и другие возможности управления подробностью5. За пределами указанного интервала в трассировку сохраняются только записи начал и завершений конструкций. Указание пустой строки в качестве значения параметра включает подробную трассировку с начала выполнения программы (в случае параметра TraceOptions.StartPoint), либо подробная трассировка собирается до завершения её выполнения (в случае параметра TraceOptions.FinishPoint). Например, если в качестве обоих параметров заданы пустые строки (по умолчанию), то трассировка с заданным уровнем подробности собирается на протяжении всего выполнения программы.

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

  1.  Обе точки заданы внутри разных подзадач одной и той же области задач. Такое задание некорректно, поэтому будет выдано сообщение об ошибке6.
  2.  Обе точки заданы внутри подзадачи одной и той же области задач. В этом случае трассировка заданной подробности будет собираться в заданном интервале только одной подзадачи. Однако пользователь отладчика может указать и всю область задач целиком, изменяя значения, указываемые в нумерации после первого символа точки. Например, при желании получить подробную трассировку не с точки 13.2.4.B по точку 13.2.6.E, а для всей области задач целиком он может указать в качестве первой точки точку 13.B, в качестве второй – 13.E.
  3.  Первая точка находится до области задач, вторая – внутри подзадачи. В этом случае, начиная с первой точки будет собираться трассировка заданной подробности, далее – только в пределах интересующей подзадачи до требуемой точки. Также как и в случае (2) можно указать отладчику выключить подробную трассировку либо перед началом области задач, либо после этой области задач.
  4.  Первая точка находится внутри подзадачи, вторая – после области задач. В этом случае трассировка заданной подробности начнёт собираться после заданной конструкции внутри требуемой подзадачи и закончится за пределами области задач в заданной точке. Также как и в случае (2) можно указать отладчику включить подробную трассировку либо с начала области задач, либо после этой области задач.
  5.  Обе точки в разных областях задач. В этом случае трассировка заданной подробности начнёт собираться после заданной конструкции внутри требуемой подзадачи первой области задач, далее, после завершения первой области задач и до начала второй области задач трассировка будет собираться для всех подзадач областей задач, расположенных между указанными областями задач (если такие есть), далее трассировка будет собираться только в пределах интересующей подзадачи второй области задач до требуемой точки.

Особенности реализации

При работе с точками начала/окончания подробной трассировки используются функции, описанные в предыдущей главе. Можно отметить, что в структуру TRACE были добавлены два поля (NUMBER *StartPoint, *FinishPoint), хранящие текущие ограничения по нумерации.

Задание ограничений на трассировку итераций

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

Введём пять параметров Ig_left, Ig_right, Iloc_left, Iloc_right, Irep_left. Будем считать, что параметр не задан, если его значение равно -1. Если все параметры не заданы (по умолчанию), то ограничения на трассировку итераций не действуют.

Опишем алгоритм ограничений на трассировку итераций:

Пусть текущий цикл последовательный. Если параметр Irep_left не задан, то текущая итерация трассируется.

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

Пусть текущий цикл параллельный. Если не задан ни один из параметров Ig_left, Ig_right, Iloc_left, Iloc_right, то текущая итерация трассируется.

Рассмотрим следующие характеристики текущего цикла:

  •  upper – массив максимальных значений переменных цикла (по каждому измерению);
  •  lower – массив минимальных значений переменных цикла;
  •  step – массив шагов переменных цикла;
  •  loc_upper – массив максимальных значений переменных цикла на данном процессоре;
  •  loc_lower – массив минимальных значений переменных цикла на данном процессоре.

Построим множества витков:

LOC_R =

при  Iloc_right ≠ -1;

, при  Iloc_right = -1.

Пусть index – массив индексов текущей итерации цикла. Очевидно, что выполняется неравенство lower[i] ≤ index[i] ≤ upper[i].

Если , то текущая итерация трассируется, в противном случае текущая итерация не трассируется.

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

Особенности реализации

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

byte was_not_traced(long *index)

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

byte out_of_bounds(long *index)

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

На время выполнения нетрассируемых итераций для повышения быстродействия отладчика вызовы отладочных функций trc_put_variable и trc_cmp_variable через указатели подменяются на вызовы функции dummy_var, которая имеет такой же прототип, как и указанные функции, но никаких действий не производит.


Глава 4. Уровень подробности контрольных сумм

Как уже было сказано выше, уровень подробности трассировки MINIMAL не позволяет обнаруживать ошибки, отличные от неправильной спецификации редукционных операций, а размер трассировки и время выполнения программы при использовании уровней подробности MODIFY и FULL высоки. Это не позволяет пользователю отлаживать программы на целевых данных. Уровень подробности контрольных сумм позволяет отлаживать программы на целевых данных, поскольку он не требует большого объёма памяти (как оперативной, так и внешней) и работает быстрее уровней подробности MODIFY и FULL7. Так же этот уровень подробности определяет (если, конечно, результаты ошибки отражаются на контрольных суммах массивов) диапазон нумерации, для которого имеет смысл рассматривать подробную трассировку. Уровень подробности контрольных сумм является в некоторой степени компромиссом между точностью локализации ошибки и размером трассировки (а так же и временем выполнения программы).

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

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

Дальнейшее рассмотрение уровня подробности контрольных сумм удобно произвести по следующему плану:

  1.  Сбор информации о читаемых и изменяемых элементах массивов и вычисление контрольных сумм этих массивов по окончании параллельных циклов и областей задач.
  2.  Запись/чтение трассировки и конфигурационного файла трассировки с контрольными суммами.
  3.  Сравнение контрольных сумм, полученных в процессе выполнения программы с контрольными суммами, прочитанными из трассировки.

Накопление контрольных сумм

К элементам массивов возможны следующие типы доступа:

  1.  чтение;
  2.  запись;
  3.  чтение и запись.

Далее, под словами «доступ к массиву» будем понимать доступ к элементам этого массива.

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

  •  TraceOptions.ChecksumMode = 1 (по умолчанию). В этом случае контрольные суммы будут вычисляться для массивов, к которым производился доступ типа b) или c).
  •  TraceOptions.ChecksumMode = 2. Контрольные суммы будут вычисляться для массивов, к которым производился доступ любого из указанных типов.

Контрольная сумма элементов массива вычисляется по следующей формуле:

где  – размеры измерений массива Array, в пределах которых меняются индексные переменные  соответственно.

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

Замечания:

  1.  Важно понимать, что вычисление контрольных сумм на многопроцессорной ЭВМ – операция достаточно дорогая (в смысле времени), в силу того, что один процессор (центральный) должен собрать значения всех локальных контрольных сумм, вычислить окончательную контрольную сумму и разослать её всем остальным процессорам.
  2.  Вычислять контрольные суммы удобно именно для параллельных конструкций (параллельных циклов и областей задач), поскольку имеется дисциплина их прохождения (любая параллельная конструкция единожды выполняется на всех процессорах текущей процессорной системы) и ограничение на вложенность (параллельные циклы могут быть вложены только в области задач, области задач не могут быть вложены ни друг в друга, ни в параллельные циклы). Таким образом, для последовательных циклов контрольные суммы не вычисляются.
  3.  Рассмотрим случай,  когда у нас имеется параллельный цикл (или область задач), а в него (или в задачу области задач) вложены один или несколько последовательных циклов. В этом случае после параллельного цикла  (или области задач) будут вычислены контрольные суммы для всех массивов, к которым был доступ непосредственно в параллельном цикле (соответственно, задаче области задач) и во вложенных последовательных циклах.

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

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

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

Уникальным идентификатором массива будем считать четвёрку:

  •  имя массива;
  •  имя файла, в котором объявлен этот массив;
  •  номер строки объявления массива;
  •  номер массива.

Номер массива вычисляется следующим образом: в списке зарегистрированных массивов ищется последний зарегистрированный массив с таким же именем, таким же именем файла и номером строки в этом файле. Если такой массив найден, то в качестве номера регистрируемого массива берётся номер найденного массива, увеличенный на единицу. Иначе (если такой массив не найден) в качестве номера регистрируемого массива принимается нулевое значение. Ситуация, в которой в одной и той же строке файла регистрируются массивы с одним и тем же именем – это инициализация в последовательном цикле элементов массива – указателей памятью, выделенной для динамического массива. Имя у этих динамических массивов одно и то же, так как значение переменной цикла компиляторами C-DVM и Fortran-DVM подставлено быть не может.

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

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

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

Последнее утверждение иллюстрирует следующий пример.

Пусть имеется функция F(X, Y), параметрами которой являются два одинаково распределённых массива и эта функция в параллельном цикле читает массив X  и пишет в массив Y. Пусть у нас есть три одинаково распределённых массива A, B и С, подходящие в качестве параметров для нашей функции. Рассмотрим следующую последовательность вызовов функции F: F(A, B), F(B, С).

Рассмотрим два случая:

  1.  Конфигурационный файл не загружен. Во время первого вызова функции F в заголовке файла трассировки будет создана конструкция параллельного цикла для цикла из тела нашей функции, в конструкции завершения этого цикла будет сохранена информация о том, что к массиву А был доступ на чтение, к массиву В – на запись. Также будут вычислены контрольные суммы для массивов А и В (или только для массива В, если TraceOptions.ChecksumMode = 1) и записаны в трассировку. Во время второго вызова функции F произойдёт поиск конструкции цикла из тела нашей функции в заголовке файла, и информация о доступе к массивам будет обновлена следующим образом: к массиву А - доступ на чтение, к массиву В - доступ на чтение и запись, к массиву С – на запись. В трассировку запишутся вычисленные контрольные суммы для массивов В и С. Если включен режим сохранения конфигурационного файла, то в него сохранится вся информация из заголовка.
  2.  Конфигурационный файл загружен. В этом случае загруженный конфигурационный файл становится заголовком трассировки, вся информация о доступе к массивам берётся из этого заголовка, поэтому отслеживания доступа к массивам не происходит. При первом вызове функции F конструкция параллельного цикла будет найдена в заголовке трассировки, и в конце цикла контрольные суммы будут вычислены и сохранены в трассировку уже для всех трёх массивов. То же самое произойдёт и во время второго вызова функции F.

Во втором случае уместен следующий вопрос: а что произойдёт, если массив С – динамический, создаётся  между двумя вызовами функции F? Во время первого вызова функции F он ещё не существует. В этом случае контрольная сумма для массива С подсчитываться не будет (у отладчика не будет информации об адресе массива). Во время второго вызова функции F контрольная сумма для массива С будет вычислена и помещена в трассировку.

Запуск программы параллельно в режиме накопления трассировки с уровнем подробности контрольных сумм недопустим без наличия конфигурационного файла или с параметром TraceOptions.TrapArraysAnyway = 1, поскольку некоторые процессоры могут не вызвать операцию подсчёта контрольных сумм из-за того что им может не достаться ни одной итерации параллельного цикла (в этом случае на этих процессорах обращений к массивам не будет).

Формат файла трассировки

В формате файлов изменилась только конструкция завершения цикла/области задач.

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

EL: <номер конструкции> (<имя>, <файл>, <строка>, <номер>, <”r”|”w”|”rw”>) ... (<имя>, <файл>, <строка>, <номер>, <”r”|”w”|”rw”>)

После номера конструкции в той же строке через пробел в скобках перечисляется информация о массивах: первые 4 поля – уникальный идентификатор массива, далее – тип доступа к массиву: чтение (”r”), запись (”w”), чтение и запись (”rw”).

В самой трассировке конструкция завершения цикла/области задач выглядит следующим образом:

EL: <номер конструкции>; {<файл>, <строка>}

CS(<имя>, <файл>, <строка>, <номер>, <доступ>)=”<значение>”

...

CS(<имя>, <файл>, <строка>, <номер>, <доступ>)=”<значение>”

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

CS(<имя>, <файл>, <строка>, <номер>, <доступ>) FAILED

Каждая строка кроме первой представляет собой описание массива либо с вычисленным значением контрольной суммы, либо с зарезервированным словом FAILED, которое означает, что контрольная сумма для данного массива не может быть вычислена (последнее может произойти в случае каких-либо ошибок в программе).  В случае невозможности подсчёта контрольной суммы для какого-либо массива на экран будет выдано соответствующее сообщение8. Контрольные суммы подсчитываются только для массивов тип доступа к которым удовлетворяет значению параметра TraceOptions.ChecksumMode.

Сравнение контрольных сумм

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

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

Реализация уровня подробности контрольных сумм

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

typedef struct tag_CHECKSUM

{

   void    *pInfo;           /* pointer to the array debugger

                                information */

   double   sum;             /* checksum of the array */

   long     lArrNo;          /* array number in the tArrays table */

   byte     accType;         /* access type: 1-read, 2-write,

                                3-read and write */

   byte     calculated;      /* 1 - if checksum is calculated,

                                0 - impossible to calculate checksum

                                    for this array

                                2 - the same as 0 + you don't need to

                                    output error message */

   void     *pAddr;          /* array address information for

                                trapping purposes */

}

CHECKSUM;

typedef struct tag_LIST

{

   byte        collect;

   CHECKSUM    *body;

   int         cursize;

   int         maxsize;

}

LIST;

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

Тип CHECKSUM используется для передачи информации функции Lib-DVM, которая вычисляет контрольные суммы для заданных массивов. Одной структуре соответствует один массив. Поле pInfo – указатель на структуру с дополнительной информацией о массиве, lArrNo – номер массива в таблице  tArrays (см. []), accType – тип доступа к элементам массива (1- чтение, 2 – запись, 3 чтение и запись), sum – поле, в которое помещается значение вычисленной контрольной суммы, calculated – флаг, определяющий, подсчитана контрольная сумма или нет (1 – контрольная сумма вычислена и хранится в поле sum, 0 – не удалось вычислить контрольную сумму для указанного массива, 2 – контрольную сумму для указанного массива вычислить не удалось, сообщение об ошибке уже выдано).

Тип LIST используется для хранения информации о доступе к массивам в заданной конструкции программы. Флаг collect определяет, требуется ли собирать информацию о доступе к массивам. Поле maxsize – количество элементов типа CHECKSUM, под которые выделена память и на которые ссылается поле body. Поле cursize – количество заполненных элементов типа CHECKSUM по указателю body. В случае необходимости хранения большего количества, чем maxsize элементов, выделяется дополнительно REALLOC_COUNT*sizeof(CHECKSUM) байт памяти при помощи функции realloc. Значение макроса REALLOC_COUNT можно переопределить, по умолчанию оно равно 5.

Функции, добавленные в отладчик системы DVM при реализации уровня подробности контрольных сумм:

void cs_compute(CHECKSUM *arrays, int count)

Функция реализует подсчёт контрольных сумм для передаваемого ей в качестве параметра массива структур CHECKSUM, количество элементов которого передаётся в параметре count. В настоящее время функция cs_compute реализована разработчиками системы времени выполнения и находится в файле maxim_k.c.

void list_init(LIST *list)

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

void list_clean(LIST *list)

Функция освобождает память, занимаемую списком, затем инициализирует список при помощи функции list_init()

void updateListA(LIST *list, void *pArrBase, byte accType)

Функция пытается найти в списке массив с адресом pArrBase, если такого массива в списке нет, то он добавляется. Информация о доступе к найденному или добавленному массиву обновляется в соответствии с полем accType

void updateListN(LIST *list, long lArrNo, byte accType)

Функция пытается найти в списке массив с номером lArrNo, если такого массива в списке нет, то он добавляется. Информация о доступе к найденному или добавленному массиву обновляется в соответствии с полем accType

void lists_uucopy(LIST *dest, LIST *src)

Функция добавляет в список dest массивы из списка src, которых в dest ещё нет. Для всех добавленных или найденных в dest массивов обновляется информация о доступе, взятая из массивов src

int list_build_checksums(LIST *list, CHECKSUM **ppChecksums)

Функция создаёт массив контрольных сумм *ppChecksums по указанному списку list. Возвращается число элементов в массиве *ppChecksums

size_t list_to_header_string(char *str, LIST *list)

Функция создаёт строку str, содержащую информацию о массивах списка list. Строка создаётся в формате файла циклов или заголовка трассировки


Глава 5. Сохранение элементов массива в заданный файл

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

Сохранение массива в момент обнаружения расхождения в контрольных суммах производится в том случае, если параметр SaveArrayFilename не является пустой строкой (этим параметром определяется имя файла, в который производится сохранение). При сохранении массива на экран выдаётся уникальный идентификатор этого массива9,10 и номер точки, в которой произошло сохранение.

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

Особенности реализации

При реализации возможностей сохранения массива в файл написано 2 функции.

void save_array(dvm_ARRAY_INFO *pArr, char *point)

Функция сохраняет массив с отладочной информацией pArr. На экран выдаётся сообщение об успехе/неудаче операции с указанием точки нумерации point

void save_array_with_ID(char *arr_id, char *point)

Функция сохраняет массив с идентификатором arr_id. На экран выдаётся сообщение об успехе/неудаче операции с указанием точки нумерации point


Глава 6. Оценка эффективности предложенных возможностей

Для наших экспериментов выберем один из тестов NASA [] – LU, переписанный на язык Фортран-DVM разработчиками системы DVM. Этот тест мы будем запускать на отладочных данных, поскольку запуск на целевых данных потребовал бы слишком много ресурсов.

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

878 CDVM$ PARALLEL (j) ON flux(*,*,j,*), SHADOW_COMPUTE

879       do j = L1, L2

880         do k = 2, nz - 1

881            do i = ist, iend

882                flux(1,i,j,k) = rsd(3,i,j,k)

883                u31 = rsd(3,i,j,k) / rsd(1,i,j,k)

884                q = 0.50d+00 * (  rsd(2,i,j,k) * rsd(2,i,j,k)

885      >                         + rsd(3,i,j,k) * rsd(3,i,j,k)

886      >                         + rsd(4,i,j,k) * rsd(4,i,j,k) )

887      >                      / rsd(1,i,j,k)

888                flux(2,i,j,k) = rsd(2,i,j,k) * u31

889                flux(3,i,j,k) = rsd(3,i,j,k) * u31 + c2 *

890      >                       ( rsd(5,i,j,k) - q )

891                flux(4,i,j,k) = rsd(4,i,j,k) * u31

892                flux(5,i,j,k) = ( c1 * rsd(5,i,j,k) - c2 * q )*u31

893             end do

894          end do

895       end do

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

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

Неинструментированная программа

(-d0 -p)

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

(-d4, -p, EnableTrace=0)

Инструментированная программа с динамическим контролем

(-d4, EnableDynControl=1)

0,14 сек

3,6 сек

1620 сек11

Таблица . Результаты последовательных запусков отладочной версии теста NASA LU с различными параметрами

Воспользуемся существующими возможностями отладки, запустим программу в режиме оценки размера трассировки с уровнями подробности FULL и MODIFY. В случае уровня подробности FULL предполагаемый размер трассировки составляет 1 337 771 861 байт, расход оперативной памяти 2 426 457 092 байт, для уровня MODIFY 383 064 655 и 746 277 668 байт соответственно. Для тестовой машины (Intel Pentium 4 – 1800 МГц, 256 Мб ОЗУ) это неприемлемо.

Попробуем использовать возможности динамического контроля DVM-указаний. Несмотря на то, что время выполнения программы с использованием динамического контроля достаточно велико (как видно из таблицы 1), динамический контроль определил доступ к нелокальной переменной в следующем цикле после того, в котором была удалена спецификация SHADOW_COMPUTE:

897 CDVM$ PARALLEL (j) ON frct(*,*,j,*)            

898       do j = jst, jend

899        do k = 2, nz - 1

900         do i = ist, iend

901                do m = 1, 5

902                   frct(m,i,j,k) =  frct(m,i,j,k)

903      >                 - ty2 * (flux(m,i,j+1,k)-flux(m,i,j-1,k))

904                end do

905             end do

906            end do

907          end do

В приведённом цикле использовались теневые грани одного из массивов, которые должны были быть обновлены в предыдущем цикле. Сообщение динамического контроля:

*** DYNCONTROL *** : Loop( No(42), Iter(2) ), Loop( No(43), Iter(2) ), Loop( No(44), Iter(2) ), Loop( No(45), Iter(1) ). File: ludv.fdv, Line: 902

Access to non-local element flux(m,i,j + 1,k).

Однако время отладки с использованием динамического контроля (27 минут) всё же может быть неприемлемо.

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

Different checksums for array ("frct", "ludv.fdv", 68, 0, "rw"): -0.3839 != -0.3328 at the point 13.E; previous correct point is 11.E.

Производя поиск в трассировке можно определить, что точка 11.E соответствует строке кода 869, точка 13.E – строке 907, ошибка была совершена именно на этом интервале.

Если программист ещё не догадался, где он ошибся, он может получить трассировку с уровнем подробности FULL на интервале от точки 11.E до 13.Е. Для этого необходимо присвоить соответствующие значения параметрам TraceOptions.StartPoint и TraceOptions.FinishPoint файла параметров. Далее необходимо повторить процедуры накопления трассировки и сравнения промежуточных результатов выполнения программы с данными трассировки.

Следующее сообщение об ошибке будет выдано первым:

(1)*** CMPTRACE *** : TraceRecord(101872), Loop( No(42), Iter(6) ), Loop( No(43), Iter(2) ), Loop( No(44), Iter(2) ), Loop( No(45), Iter(1) ). File: ludv.fdv, Line: 902

Different DOUBLE values: 2.8509 != 0.0000.

Как видно, новые возможности, предложенные в настоящей работе, позволили локализовать ошибку гораздо быстрее, чем возможности динамического контроля DVM-указаний. Суммарное время выполнения в случае использования новых возможностей составляет 14,1 + 45,4 + 15,2 + 66,1 секунд = 140,8 секунд против 1620 секунд в случае использования динамического контроля DVM-указаний.

В таблице 2 приведены времена выполнения программы. Стоит заметить, что уровень подробности трассировки MINIMAL не позволяет локализовать ошибку (хотя время выполнения программы с этим уровнем подробности вполне сравнимо со временем выполнения программы с уровнем подробности контрольных сумм). Запуски программы с накоплением трассировки и сравнением промежуточных результатов выполнения с данными трассировки при уровнях MODIFY и FULL не производились, поскольку (как было указано в начале главы) размер трассировки и требования к объему оперативной памяти настолько велики, что для тестовой машины это неприемлемо. При уровне подробности NULL накопление трассировки не производится, в файл трассировки сохраняется только заголовок (поэтому сравнение промежуточных данных с данными трассировки невозможно).

уровень CHECKSUM

уровень FULL на интервале от 11.Е до 13.Е

уровень MINIMAL

уровень NULL

режим накопления трассировки

14,1 сек

15, 2 сек

13,1 сек

8,2 сек

режим сравнения трассировки при эмуляции двух процессоров

45,4 сек

66,1 сек12

19,3 сек

-

размер файла трассировки

12 575 992 байт

16 708 133 байт

12 550 535 байт

15 346 байт

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

Можно заметить, что если время выполнения программы или объем трассировки при запуске программы с ограничением на интервал трассировки будут велики пользователь может дополнительно указать ограничение на трассируемые итерации (см. Главу 3).

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


Заключение

В данной дипломной работе предложены новые возможности, существенно повышающие эффективность отладки DVM-программ, что и было показано в ходе экспериментов с тестом NASA [] LU.

В процессе выполнения работы

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

Предложенные возможности были успешно протестированы на демонстрационных программах, поставляемых вместе с системой DVM, а так же на тесте NASA [] LU.

Изменения коснулись 13 файлов отладчика. Написано 20 новых функций, во многие существующие функции отладчика внесены изменения.

Разработанные возможности рекомендованы к применению в новых версиях системы DVM.


Литература

  1.  Документация к системе DVM. http://www.keldysh.ru/dvm
  2.  Rajkumar Buyya, High Performance Cluster Computing (Architecture, Systems, and Applications), PowerPoint presentation. http://www.buyya.com 04 Apr 2002.
  3.  Высокопроизводительные параллельные вычисления на кластерных системах. Материалы Международного научно-практического семинара./Под ред. проф. Стронгина. Нижний Новгород: Изд-во Нижегородского Университета, 2002, стр. 83-90.
  4.  MPI: A Message-Passing Interface Standard. http://www.mpi-forum.org
  5.  High Performance Fortran language specification // High Performance Fortran Forum. Scientific Programming. – 1993. – Vol. 2. – Р.1-170.
  6.  OpenMP Consortium. http://www.openmp.org
  7.  High Performance Debugging Forum. http://www.ptools.org/hpdf
  8.  Страничка отладчика Guard. http://www.csse.monash.edu.au/~davida/guard/index.html
  9.  Support for Debugging Automatically Parallelized Programs. Robert Hood, Gabriele Jost, NASA Ames Research Center. http://arxiv.org/ftp/cs/papers/0012/0012006.pdf
  10.  Коновалов Н. А., Крюков В. А., Погребцов А. А., Сазанов Ю. Л. C-DVM – язык разработки мобильных параллельных программ.– М.: Препринт ИПМ им. М.В.Келдыша РАН, 1997. – №86. – 37 с.
  11.  Konovalov N. A., Krukov V. A., Mihailov S. N. and Pogrebtsov A. A. Fortran DVM – a Language for Portable Parallel Programs Development // Proceedings of Software For Multiprocessors and Supercomputers: Theory, Practice, Experience
  12.  Крюков В. А., Удовиченко Р. В. Отладка DVM-программ. – М.: Препринт ИПМ им. М.В.Келдыша РАН, 1999. – №56. – 26 с.
  13.  Удовиченко Р. В. Отладка DVM-программ. Диссертация на соискание ученой степени кандидата физико-математических наук, 2000 г.
  14.  NAS Parallel Benchmarks Group, NASA Ames Research Center, NAS parallel benchmarks 2.3. http://www.nas.nasa.gov/NAS/NPB/


Приложение 1. Сообщения об ошибках отладчика системы DVM (добавленные)

Сообщения об ошибках, связанные с нумерацией конструкций:

Invalid start point value: TraceOptions.StartPoint = '<erroneous string>'.

Неверно задана точка начала подробной трассировки (синтаксическая ошибка)

Invalid finish point value: TraceOptions.FinishPoint = '<erroneous string>'.

Неверно задана точка окончания подробной трассировки (синтаксическая ошибка)

Start point is not less than finish point.

Точка нумерации, заданная в качестве начальной не предшествует точке окончания трассировки

Start and finish points are incomparable values.

Точки начала и окончания подробной трассировки несравнимы, т.е. находятся в разных подзадачах одной и той же области задач

Start point <point1> implies task region but actual construction is parallel loop; starting verbose trace from the point <point2>.

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

Finish point <point1> implies task region but actual construction is parallel loop; finishing verbose trace at the point <point2>.

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

Assertion failed

Нарушено необходимое условие. Внутренняя ошибка

Сообщения об ошибках, возникающие при неверном указании параметров, отвечающих за ограничения на итерации:

Incorrect parameter TraceOptions.Ig_left value.

Неверное значение параметра TraceOptions.Ig_left

Incorrect parameter TraceOptions.Ig_right value.

Неверное значение параметра TraceOptions.Ig_right

Incorrect parameter TraceOptions.Iloc_left value.

Неверное значение параметра TraceOptions.Iloc_left

Incorrect parameter TraceOptions.Iloc_right value.

Неверное значение параметра TraceOptions.Iloc_right

Incorrect parameter TraceOptions.Irep_left value.

Неверное значение параметра TraceOptions.Irep_left

Incorrect parameter TraceOptions.Irep_right value.

Неверное значение параметра TraceOptions.Irep_right

Parameter TraceOptions.Irep_right is reserved for further versions; it is switched off for this run.

Параметр TraceOptions.Irep_right зарезервирован для будущих версий. В текущем запуске он будет выключен

Сообщения об ошибках, связанные с уровнем подробности контрольных сумм:

Incorrect or absent configuration file for parallel checksum tracelevel.

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

TraceOptions.TrapArraysAnyway = 1 can not be specified with parallel checksum tracelevel.

Параметр TraceOptions.TrapArraysAnyway = 1 нельзя задавать при накоплении параллельной трассировки с уровнем подробности контрольных сумм

Incorrect parameter value: TraceOptions.ChecksumMode = <value>.

Неверное значение параметра TraceOptions.ChecksumMode

TraceOptions.ChecksumMode = 0 is not supported yet.

Значение параметра TraceOptions.ChecksumMode = 0 в настоящий момент не поддерживается

Incorrect parameter value: TraceOptions.TrapArraysAnyway = %d.

Неверное значение параметра TraceOptions.TrapArraysAnyway

Found access to array without registration.

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

Different checksums for array (<array_id>, <access>): <value1> != <value2> at the point <point1>; previous correct point is (absent | <point2>)

Значения <value1> и <value2> контрольных сумм массива <array_id> с доступом <access> различаются в точке <point1>. Точки, в которой контрольные суммы совпадали либо не существует (absent), либо такой точкой является <point2>

Unable to compute checksum for array (<array_id>) at the point <point>.

Контрольная сумма для массива с идентификатором array_id не может быть вычислена в точке point (возможно, в этой точке указанный массив ещё не создан, а информация о нём была загружена из конфигурационного файла)

Reference to undefined array

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

Warning: failed checksums found. They won't be recounted

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

Instances of replicated array (<array_id>) do not match at the point <point>

При подсчёте контрольных сумм обнаружилось, что экземпляры массива <array_id>, размноженного по всем процессорам имеют различные локальные контрольные суммы

Сообщения об ошибках, связанные с сохранением массива в файл:

Can’t open file <filename> for writing.

Невозможно открыть файл <filename> для записи

Array (<array_id>) cannot be saved at the point <point>.

Массив с идентификатором <array_id> невозможно сохранить в точке нумерации <point> (возможно, в этой точке указанный массив ещё не создан, а информация о нём была загружена из конфигурационного файла)

An error occurred during saving array (<array_id>) to file <filename> at the point <point>.

При сохранении массива с идентификатором <array_id> в файл <filename> в точке <point> произошла ошибка

Array (<array_id>) has been successfully saved to file <filename> at the point <point>.

Массив с идентификатором <array_id> был успешно сохранён в файл <filename> в точке <point>

Array (<array_id>) was not found at the point <point>.

Массив с идентификатором <array_id> в точке <point> не зарегистрирован (и, следовательно, не может быть сохранён)

Invalid array ID specification <erroneous string>.

Неверная спецификация идентификатора массива (синтаксическая ошибка)


Приложение 2. Параметры отладчика системы DVM (добавленные)

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

TraceOptions.StartPoint, тип char *

Данный параметр определяет точку нумерации, с которой необходимо включить подробную трассировку, уровень которой определяется параметром TraceOptions.TraceLevel

TraceOptions.FinishPoint, тип char *

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

Следующие параметры определяют ограничения на трассируемые итерации. Эти параметры имеют тип int и умолчанию их значения равны -1. Об их использовании более подробно см. Главу 3.

TraceOptions.Ig_left

TraceOptions.Ig_right

TraceOptions.Iloc_left

TraceOptions.Iloc_right

TraceOptions.Irep_left

TraceOptions.Irep_right (заблокирован)

Параметры, введённые в уровне подробности трассировки контрольных сумм:

TraceOptions.ChecksumMode, тип byte

В зависимости от значения данного параметра подсчёт контрольных сумм будет производиться для всех массивов (TraceOptions.ChecksumMode = 2), либо для массивов, к элементам которых был доступ на запись, либо на чтение и запись (TraceOptions.ChecksumMode = 1, по умолчанию)

TraceOptions.TrapArraysAnyway, тип byte

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

Параметры, управляющие возможностями сохранения элементов массива в файл:

TraceOptions.SaveArrayFilename, тип char *

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

TraceOptions.SaveArrayID, тип char *

Если идентификатор массива, определяемый данным параметром, а также параметр TraceOptions.SaveArrayFilename  не являются пустыми строками, то в точке, определяемой параметром TraceOptions.FinishPoint массив с указанным идентификатором будет сохранён в заданный файл. Если данный параметр пустая строка “” (по умолчанию), то сохранение элементов массива в точке TraceOptions.FinishPoint (если задана) производиться не будет

1 Далее под термином «отладка» будем понимать деятельность, направленную на обнаружение и исправление ошибок в программе (отладка функциональности, функциональная отладка) вне зависимости от использования процессов исполнения программ.

2 Все последовательные циклы представляются отладчику как одномерные

3 На сегодняшний день отладочные интерфейсы системы DVM не предоставляют функциям отладчика возможность отследить k последних итераций последовательного цикла

4 Такую информацию пользователь может получить с помощью уровня подробности контрольных сумм, см. Главу 4.

5 Более подробно см. [, , ]

6 Сообщения об ошибках и их краткие описания даны в Приложении 1

7 Результаты сравнения производительности см. в главе 6

8 Список сообщений отладчика находится в Приложении 1

9 Сообщения отладчика описаны в Приложении 1.

10 Напомним, что уникальным идентификатором массива является строка <имя массива>, <файл объявления>, <строка объявления>, <номер массива>.

11 Динамический контроль досрочно завершил выполнение программы по исчерпании максимально допустимого количества ошибок

12 Отладчик досрочно завершил выполнение программы по исчерпании максимально допустимого количества ошибок

: cmptrace.c, cmptrace.ext, cmptrace.typ, cmptrace.var, cntrlerr.typ, cntrlerr.var, dbgdec.c, getpar.c, trc_cmp.c, trc_put.c, trc_read.c, trc_wrt.c
GLOB_L
=

при  Ig_left ≠ -1;

, при  Ig_left = -1.

GLOB_R =

при  Ig_right ≠ -1;

, при  Ig_right = -1.

LOC_L =

при  Iloc_left ≠ -1;

, при  Iloc_left = -1.


 

А также другие работы, которые могут Вас заинтересовать

85071. Законодательная и нормативно-правовая база по организации борьбы с терроризмом 29.94 KB
  Изучаемые вопросы Правовые основы противодействия терроризму. Основные принципы противодействия терроризму. Сообщить учащимся о том что правовую основу борьбы с терроризмом составляют Конституция РФ Уголовный кодекс РФ Федеральный закон О противодействии терроризму и другие федеральные законы общепризнанные принципы и нормы международного права международные договоры РФ указы и распоряжения Президента РФ постановления и распоряжения Правительства РФ а также принимаемые в соответствии с ними другие нормативные правовые акты...
85072. Система борьбы с терроризмом 29.31 KB
  Силы и средства привлекаемые для проведения контртеррористической операции. Единое управление силами и средствами входящими в состав группировок включая переподчинение представителей и подразделений федеральных органов исполнительной власти осуществляет руководитель контртеррористической операции. Все военнослужащие сотрудники и специалисты привлекаемые для проведения контртеррористической операции с момента начала контртеррористической операции и до ее окончания подчиняются руководителю контртеррористической операции. В заключение...
85073. Правила поведения при угрозе террористического акта 32.57 KB
  Правила поведения при угрозе террористического акта Цель урока. Обсудить с учащимися правила безопасного поведения в различных ситуациях террористического характера. Изучаемые вопросы Правила безопасного поведения при угрозе взрыва и при взрыве. Не прикасайтесь к находке и не давайте этого делать другим Далее обсудить с учащимися правила безопасного поведения при следующих ситуациях.
85074. Государственная политика противодействия наркобизнесу. Профилактика наркомании 32.58 KB
  Профилактика наркомании. Привлечь внимание учащихся к факту губительного распространения наркомании среди молодежи познакомить их с нормативноправовой основой противодействия наркомании; обсудить статью Уголовного кодекса РФ в которой предусмотрены наказания за действия связанные с наркотическими и психотропными веществами. Сформировать у учащихся убеждение в том что самая эффективная профилактика наркомании это индивидуальная система самовоспитания. Познакомить учащихся с психологической основой по формированию индивидуальной системы...
85077. Вредные привычки, их влияние на здоровье. Профилактика вредных привычек 34.63 KB
  Профилактика вредных привычек. Одна из таких угроз возникновение а главное глобальное распространение вредных привычек. Назовите социальные причины вредных привычек и их последствия. Ощущаем ли мы эти последствия в повседневной жизни Как ты сам борешься с вредными привычками Учитель предлагает обсудить проблему таких вредных привычек как пьянство и алкоголизм табакокурение и наркомания.
85078. Алкоголизм и курение, их профилактика 44.7 KB
  Познакомить учащихся с физиологическими и социальными последствиями употребления алкоголя. К сожалению употребление алкоголя давно стало элементом человеческой культуры и так же давно передовые представители человечества говорили о пагубности этой привычки. Токсическое воздействие алкоголя прежде всего сказывается на деятельности нервной системы. Если содержание алкоголя в крови принять за 1 единицу то в печени оно будет равно 145 а в головном мозге 175.
85079. Наркомания – прямая угроза жизни и здоровью человека 41.3 KB
  Цель урока: Познакомить учащихся с физиологическими и социальными последствиями употребления наркотиков Изучение нового материала. Каков возраст подавляющего большинства наркоманов В каком возрасте люди начинают приобщаться к наркотикам Как вы думаете что является главной причиной всемирного распространения наркотиков Существует ли юридическая ответственность за употребление наркотиков А за их хранение За распространение Можно ли лечением снять наркотическую зависимость Можно ли окончательно излечиться от наркомании Какая по...