Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

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

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
Тестирование параллельных программ

Тестирование параллельных программ

02 Ноя 2008

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

Введение

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

Мы все-таки разделим эти два понятия, и сосредоточимся в этой статье на тестировании параллельного программного обеспечения.

Тестирование программного обеспечения - процесс выявления ошибок в программном обеспечении с использованием различных инструментов и анализ работоспособности программы конечными пользователями [1].

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

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

1. Сложности тестирования параллельных программ

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

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

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

2. Методики поиска ошибок в параллельных программах

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

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

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

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

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

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

Динамический анализ требует запуска программ, чувствителен к среде исполнения, существенно замедляет скорость выполнения приложения. Достаточно трудно осуществить покрытие тестами всего параллельного кода. Часто зафиксировать состояние гонки (race conditions) удается, только если оно было в данном сеансе работы программы. То есть, если средство динамического анализа сообщает, что ошибок нет, вы все равно не можете быть уверены в этом.

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

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

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

3. Новые технологии - новые инструменты

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

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

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

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

До недавнего времени направление статического анализа OpenMP программ практически было не освоено. В качестве примера можно привести, пожалуй, только достаточно качественную диагностику выполняемую компилятором Sun Studio. Статический анализатор VivaMP заполнил это нишу. Это специализированный инструмент для поиска ошибок в параллельных программах, разработанных с использованием технологии OpenMP на языке Си и Си++ [5].

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

int sum1 = 0;
int sum2 = 0;
#pragma omp parallel for 
  for (size_t i = 0; i != n; ++i)
  {
    sum1 += array[i]; // V1205
    #pragma atomic
    sum2 += array[i]; //Fine
  }

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

int *ptr;
...
#pragma omp flush(ptr) // V1202
int value = *ptr;

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

#pragma omp critical
{
  a++;  //Slow
}
#pragma omp atomic
a++; //Good

Заключение

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

Библиографический список

Популярные статьи по теме
Бесплатный PVS-Studio для тех, кто развивает открытые проекты

Дата: 22 Дек 2018

Автор: Андрей Карпов

В канун празднования нового 2019 года команда PVS-Studio решила сделать приятный подарок всем контрибьюторам open-source проектов, хостящихся на GitHub, GitLab или Bitbucket. Им предоставляется возмо…
Как и почему статические анализаторы борются с ложными срабатываниями

Дата: 20 Мар 2017

Автор: Андрей Карпов

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

Дата: 19 Май 2017

Автор: Андрей Карпов

Возможно, читатели помнят мою статью под названием "Эффект последней строки". В ней идёт речь о замеченной мной закономерности: ошибка чаще всего допускается в последней строке однотипных блоков текс…
PVS-Studio ROI

Дата: 30 Янв 2019

Автор: Андрей Карпов

Время от времени нам задают вопрос, какую пользу в денежном эквиваленте получит компания от использования анализатора PVS-Studio. Мы решили оформить ответ в виде статьи и привести таблицы, которые по…
Как PVS-Studio оказался внимательнее, чем три с половиной программиста

Дата: 22 Окт 2018

Автор: Андрей Карпов

PVS-Studio, как и другие статические анализаторы кода, часто выдаёт ложные срабатывания. Но не стоит спешить считать странные срабатывания ложными. Это короткая история о том, как PVS-Studio вновь ок…
Эффект последней строки

Дата: 31 Май 2014

Автор: Андрей Карпов

Я изучил множество ошибок, возникающих в результате копирования кода. И утверждаю, что чаще всего ошибки допускают в последнем фрагменте однотипного кода. Ранее я не встречал в книгах описания этого …
Статический анализ как часть процесса разработки Unreal Engine

Дата: 27 Июн 2017

Автор: Андрей Карпов

Проект Unreal Engine развивается - добавляется новый код и изменятся уже написанный. Неизбежное следствие развития проекта - появление в коде новых ошибок, которые желательно выявлять как можно раньш…
PVS-Studio для Java

Дата: 17 Янв 2019

Автор: Андрей Карпов

В седьмой версии статического анализатора PVS-Studio мы добавили поддержку языка Java. Пришло время немного рассказать, как мы начинали делать поддержку языка Java, что у нас получилось и какие дальн…
Главный вопрос программирования, рефакторинга и всего такого

Дата: 14 Апр 2016

Автор: Андрей Карпов

Вы угадали, ответ - "42". Здесь приводится 42 рекомендации по программированию, которые помогут избежать множества ошибок, сэкономить время и нервы. Автором рекомендаций выступает Андрей Карпов - тех…
Характеристики анализатора PVS-Studio на примере EFL Core Libraries, 10-15% ложных срабатываний

Дата: 31 Июл 2017

Автор: Андрей Карпов

После большой статьи про проверку операционной системы Tizen мне было задано много вопросов о проценте ложных срабатываний и о плотности ошибок (сколько ошибок PVS-Studio выявляет на 1000 строк кода)…

Комментарии (0)

Следующие комментарии

На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять