Информационно-аналитический портал
Высокопроизводительные
вычисления на WINDOWS-кластерах
  

 
 
 Главная
 Новости
 Как создать Windows-кластер
 Компьютеры
 Технологии
 Библиотеки, пакеты, приложения
 Параллельное программирование
 Проектирование 
 Отладка 
 Профилирование и оптимизация 
 Метакомпьютинг, GRID
 Обучение
 Исследования
 Ресурсы Windows CCS
 Сообщество WinHPC
 Форум
 
  
Войти
Зарегистрироваться
Забыли пароль?
  
 
 

Процесс отладки, типичные ошибки параллельных программ

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

Процесс отладки в общем случае можно разбить на следующие шаги:

  • определение факта наличия ошибки;
  • поиск (локализация) ошибки;
  • выяснение причин ошибки;
  • определение способа устранения ошибки;
  • устранение ошибки.

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

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

Шаг третий – выяснение причин ошибки. Задача здесь – понять, почему ошибка возникла. Отсюда во многих случаях автоматически вытекает способ ее устранения (задача шага четвертого). Можно, конечно, выяснить условия, ведущие к проявлению ошибки (некое сочетание значений переменных, например) и просто вставить в код заплатку именно для этого случая. Данный вариант мы здесь не рассматриваем.

Типичные ошибки в многопоточных программах: гонки данных (data races), тупики (deadlocks), потоки в состоянии ожидания (stalled threads), потерянные сигналы (lost signals), заброшенные замки (abandoned locks).

Приведем краткое описание каждого вида.

  • Гонки данных. Возникают, когда несколько потоков работают с разделяемыми данными и конечный результат зависит от соотношения скоростей потоков. Пусть, например, один поток выполняет над общей переменной x операцию x = x + 3, а второй поток – операциюx = x + 5. Данные операции для каждого потока фактически разбиваются на три отдельных подоперации: считать x из памяти, увеличить x, записать x в память. В зависимости от взаимного порядка выполнения потоками подопераций финальное значение переменной x может быть больше исходного на 3, 5 или 8. Гонка данных возможна и в случае, когда один поток пишет в переменную, а остальные только читают из нее.
  • Тупики. Взаимная блокировка потоков, ожидающих наступление некоторого события для продолжения работы. Типичный пример тупика, когда нулевой поток занял для использования ресурс 1 и ожидает предоставления ему ресурса 2, а первый поток занял ресурс 2 и ожидает предоставления ему ресурса 1.
  • Потоки в состоянии ожидания. Одно из состояний потока в многозадачной операционной системе – ожидание. Поток переходит в него, когда для продолжения выполнения ему требуется наступление некоторого внешнего события. Если пребывание потока в этом состоянии продолжается слишком долго, ITC рапортует об ошибке типа stalled thread. Интервал времени, по истечении которого выдается данная диагностика, может быть задан в настройках ITC.
  • Потерянные сигналы. Возникают, когда поток ожидает наступление некоторого события, произошедшего прежде, чем поток пришел в состояние готовности к его приему и обработке. В результате поток никогда не сможет выйти из состояния ожидания.
  • Заброшенные замки. Возникают в ситуации, когда поток захватил некоторый ресурс (критическую секцию, мьютекс) и был снят с выполнения по той или иной причине. В результате ресурс не может быть освобожден. Если он требуется другому потоку, это приведет к бесконечному ожиданию.

Список пакетов, используемых при отладке параллельных программ

 

Новости

30.11.2008 6:04
20.10.2008 14:42
20.10.2008 14:31
29.09.2008 17:17
29.09.2008 17:05
 

  

© ННГУ, Центр компетенции в области высокопроизводительных вычислений на основе технологий Майкрософт, 2007