Задача знакомства программистов с областью разработки параллельных приложений становится все актуальней. Данная статья является кратким введением в создание многопоточных приложений, основанных на технологии OpenMP. Описаны подходы к отладке и оптимизации параллельных приложений.
Неудачная попытка сравнить PVS-Studio (VivaMP) и Intel C/C++ ("Parallel Lint")Tatyanazaxarova
Изначально статья должна была носить название "Сравнение диагностических возможностей PVS-Studio (VivaMP) и Intel C/C++ Compiler ("Parallel Lint"). Отсутствие на данный момент достаточного количества информации о "Parallel Lint" ограничило возможности автора, и статья представляет собой предварительный вариант сравнения. Полный вариант статьи с корректным сравнением будет доступен читателю в будущем. Обратите внимание, что содержание статьи актуально на момент публикации. В дальнейшем возможно изменение диагностических возможностей обоих продуктов.
Тестирование параллельного программного обеспечения представляет собой более сложную задачу по сравнению с тестированием последовательной программы. Программист должен знать о подводных камнях при тестировании параллельного кода, имеющихся методологиях и инструментарии.
Статья рассказывает о новом направлении в развитии статических анализаторов кода - верификации параллельных программ. В статье рассказывается о нескольких статических анализаторах, которые могут претендовать на звание "Parallel Lint".
ПРИМЕНЕНИЕ ГЕНЕТИЧЕСКИХ АЛГОРИТМОВ К ГЕНЕРАЦИИ ТЕСТОВ ДЛЯ АВТОМАТНЫХ ПРОГРАММITMO University
Описан подход к автоматизации тестирования автоматных программ. Для формализации требований спецификации к модели и объектам управления предлагается использовать контракты. Тест описывается как последовательность переходов в модели. Для автоматизации процесса создания кода теста предложен генетический алгоритм, который позволяет находить значения переменных, удовлетворяющие условиям на переходах.
32 подводных камня OpenMP при программировании на Си++Tatyanazaxarova
С распространением многоядерных систем задача параллельного программирования становится все более и более актуальной. Данная область, однако, является новой даже для большинства опытных программистов. Существующие компиляторы и анализаторы кода позволяют находить некоторые ошибки, возникающие при разработке параллельного кода. Многие ошибки никак не диагностируются. В данной статье приводится описание ряда ошибок, приводящих к некорректному поведению параллельных программ, созданных на основе технологии OpenMP.
Инструмент для программистов VivaMP предназначен для помощи разработчикам параллельных программ на базе OpenMP. В статье приведен краткий обзор программного продукта.
Трудности сравнения анализаторов кода или не забывайте об удобстве использованияTatyanazaxarova
Желание пользователей сравнить между собой разные анализаторы кода понятно и естественно. Однако реализовать это желание совсем не так просто как может показаться на первый взгляд. Дело в том, что непонятно какие конкретно факторы между собой сравнивать.
Неудачная попытка сравнить PVS-Studio (VivaMP) и Intel C/C++ ("Parallel Lint")Tatyanazaxarova
Изначально статья должна была носить название "Сравнение диагностических возможностей PVS-Studio (VivaMP) и Intel C/C++ Compiler ("Parallel Lint"). Отсутствие на данный момент достаточного количества информации о "Parallel Lint" ограничило возможности автора, и статья представляет собой предварительный вариант сравнения. Полный вариант статьи с корректным сравнением будет доступен читателю в будущем. Обратите внимание, что содержание статьи актуально на момент публикации. В дальнейшем возможно изменение диагностических возможностей обоих продуктов.
Тестирование параллельного программного обеспечения представляет собой более сложную задачу по сравнению с тестированием последовательной программы. Программист должен знать о подводных камнях при тестировании параллельного кода, имеющихся методологиях и инструментарии.
Статья рассказывает о новом направлении в развитии статических анализаторов кода - верификации параллельных программ. В статье рассказывается о нескольких статических анализаторах, которые могут претендовать на звание "Parallel Lint".
ПРИМЕНЕНИЕ ГЕНЕТИЧЕСКИХ АЛГОРИТМОВ К ГЕНЕРАЦИИ ТЕСТОВ ДЛЯ АВТОМАТНЫХ ПРОГРАММITMO University
Описан подход к автоматизации тестирования автоматных программ. Для формализации требований спецификации к модели и объектам управления предлагается использовать контракты. Тест описывается как последовательность переходов в модели. Для автоматизации процесса создания кода теста предложен генетический алгоритм, который позволяет находить значения переменных, удовлетворяющие условиям на переходах.
32 подводных камня OpenMP при программировании на Си++Tatyanazaxarova
С распространением многоядерных систем задача параллельного программирования становится все более и более актуальной. Данная область, однако, является новой даже для большинства опытных программистов. Существующие компиляторы и анализаторы кода позволяют находить некоторые ошибки, возникающие при разработке параллельного кода. Многие ошибки никак не диагностируются. В данной статье приводится описание ряда ошибок, приводящих к некорректному поведению параллельных программ, созданных на основе технологии OpenMP.
Инструмент для программистов VivaMP предназначен для помощи разработчикам параллельных программ на базе OpenMP. В статье приведен краткий обзор программного продукта.
Трудности сравнения анализаторов кода или не забывайте об удобстве использованияTatyanazaxarova
Желание пользователей сравнить между собой разные анализаторы кода понятно и естественно. Однако реализовать это желание совсем не так просто как может показаться на первый взгляд. Дело в том, что непонятно какие конкретно факторы между собой сравнивать.
Регулярное использование статического анализа кода в командной разработкеTatyanazaxarova
Технологии статического анализа кода применяются в компаниях со зрелыми процессами разработки программного обеспечения. Однако уровень применения и внедрения в процесс разработки инструментов анализа кода может быть различным. Начиная от ручного запуска анализатора "время от времени" или при поиске трудноуловимых ошибок, и кончая ежедневным автоматическим запуском или запуском при добавлении нового исходного кода в систему контроля версий.
В статье рассмотрены различные уровни использования технологий статического анализа кода в командной разработке, показано как "перевести" процесс с одного уровня на другой. В качестве примера в статье используется разрабатываемый авторами анализатор кода PVS-Studio.
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Andrey Karpov
Этот документ рекламирует статический анализатор PVS-Studio. Описывается, как использование PVS-Studio уменьшит количество ошибок в коде проекта на языке C/C++/C++11 и сократит затраты на тестирование, отладку и сопровождение кода. Приводится большое количество примеров ошибок, найденных анализатором в различных Open-Source проектах. Документ описывает PVS-Studio на момент версии 4.38 от 12 октября 2011 и, как следствие, не отражает возможности следующих версий. Чтобы познакомиться с новыми возможностями, предлагаем посетить сайт продукта <a>http://www.viva64.com</a> или поискать обновленный вариант этой статьи.
Интервью с Дмитрием Вьюковым – автором верификатора Relacy Race Detector (RRD)Tatyanazaxarova
Интервью с Дмитрием Вьюковым - автором инструмента Relacy Race Detector (RRD) для верификации параллельных приложений. В статье вы узнаете об истории создания RRD, его основных возможностях, а также о некоторых других аналогичных инструментах и их отличии от RRD.
Получасовая презентация по Java 9. Конечно, рассказать можно много больше, да и часть выводов прозизносил вслух, но в любом случае, если интересна Java 9, то изучение можно начать со ссылок в конце презентации.
Критика, предложения приветствуются.
На встрече мы поговорим о том, как не бояться изменений и как быть к ним готовым. Дадим определение АОП. Рассмотрим проблемы, хорошо решаемые инструментами АОП. Построим модульную систему, применяя АОП. Сравним динамический и статический подходы в АОП. Дадим рекомендации по применению АОП.
Вас ждет река теории впадающая в море практики.
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...yaevents
Александр Петренко, ИСП РАН
Профессор, доктор физико-математических наук, заведующий отделом технологий программирования Института системного программирования (ИСП РАН), профессор ВМК МГУ. Основные работы в областях: формализация требований, генерация тестов на основе формализованных требований и формальных моделей (model based testing – MBT). Приложения: тестирование операционных систем и распределенных систем, тестирование компиляторов, верификация дизайна микропроцессоров, формализация стандартов на API операционных систем и телекоммуникационных протоколов. Сопредседатель оргкомитетов International MBT workshop (http://www.mbrworkshop.org/), Spring Young Researcher Colloquium on Software Engineering – SYRCoSE (http://syrocose.ispras.ru), городского семинара по технологиям разработки и анализа программ ТРАП/SDAT (http://sdat.ispras.ru/).
Тема доклада
Модели в профессиональной инженерии и тестировании программ.
Тезисы
Model Based Software Engineering (MBSE) является расширением подхода к разработке программ на основе моделей. В MBSE в отличие, например, от MDA (Model Driver Architecture) существенное внимание уделяется не только задачам собственно проектирования и разработки кода, но и задачам других фаз жизненного цикла – анализу требований, верификации и валидации, управлению требованиями на всех фазах жизненного цикла. Model Based Testing (MBT) хронологически возник гораздо раньше, чем MBSE и MDA, однако его место в разработке программ в полной мере раскрылось вместе с развитием MBSE. По этой причине MBT и MBSE следует рассматривать в тесной связке. В докладе будут рассмотрены концепции MBSE-MDA-MBT, основные источники и виды моделей, которые используются в этих подходах, методы генерации тестов на основе моделей, известные инструменты для
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...ITMO University
При создании систем со сложным поведением важную роль играет контроль качества разрабатываемых программ. Цена ошибки в таких системах может быть слишком велика, поэтому важно не просто проверить соответствие создаваемой программы всем предъявленным к ней требованиям, но и сделать этот процесс эффективным, максимально автоматизировав его. На практике этого можно добиться, формализовав все требования к программе и храня полученную исполнимую спецификацию непосредственно вместе с кодом программы. Рассмотрены существующие методы контроля качества современных программных систем и автоматных программ, а также описан процесс создания среды, позволяющей поддержать сразу три подхода к проверке качества программ с явным выделением состояний: проверку на модели, модульное тестирование и контракты. Предложенный подход позволяет сохранить корректность записи сформулированных требований при изменении самой программы, а также интерактивно контролировать ее качество.
Специфика разработки и тестирования статического анализатораAndrey Karpov
В докладе я расскажу об особенностях разработки и тестирования такого программного продукта, как статический анализатор. Опишу как стандартные методики тестирования, которые мы используем (обзоры кода, Unit и UI-тесты, нагрузочное тестирование), так и специфические, позволяющие контролировать качество поиска ошибок при внесении доработок в ядро анализатора.
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...Tatyanazaxarova
Одним из нововведений в последних версиях MSBuild/Visual Studio для компиляторов Visual C++ стала новая система минимальной сборки (также известная как инкрементная сборка), основанная на отслеживании зависимостей между входными и выходными данными при работе компилятора и позволяющая осуществлять пересборку только для файлов, затронутых модификацией исходного кода или не имеющих связанных с ними выходных объектных файлов. В отличие от старой методики минимальной пересборки, завязанной на генерируемые компилятором cl.exe файлы состояний (idb-файлы, Minimal Rebuild Dependancy Database, ключ /Gm) и обладавшей рядом недостатков (как например затруднённость распараллеливания сборки из-за конфликтов доступа и отсутствие прямого отслеживания выходных объектный файлов), новая система не зависит от типа используемых сборочных инструментов (может использоваться как для компиляции, так и для линковки) и имеет открытый API. Данная новинка позволила интегрировать проверку кода анализатором PVS-Studio в процесс разработки на C/C++ с использованием инкрементных пересборок для последней версии Visual Studio 2010. Эта возможность появилась в версии PVS-Studio 4.30.
Этюды о буферизации: асинхронные оповещения, репликация обновлений, объединен...corehard_by
Практика разработки конкретного приложения может приводить к постановке задачи, которая, в зрелом размышлении, оказывается достаточно общей, чтобы вычленить её в абстракцию, потенциально полезную для множества различных приложений. Приведение решения к виду, пригодному для многократного применения, в отличие от решения, отвечающего нуждам конкретного приложения, требует дополнительных мыслительных усилий по выделению вариативных аспектов задачи, и по их моделированию средствами языка. В докладе представлен опыт реализации трёх абстракций, объединенных общей темой — буферизацией данных при многопоточной обработке. Показан ход мысли от анализа задачи до реализации средствами языка C++17.
Сам по себе рост размера структур не является ошибкой, но может приводить к потреблению необоснованного количества памяти и в результате к замедлению скорости работы программы. Будем рассматривать данный паттерн не как ошибку, но как причину неэффективности 64-битного кода.
Процессоры работают эффективнее, когда имеют дело с правильно выровненными данными. А некоторые процессоры вообще не умеют работать с не выровненными данными.
Регулярное использование статического анализа кода в командной разработкеTatyanazaxarova
Технологии статического анализа кода применяются в компаниях со зрелыми процессами разработки программного обеспечения. Однако уровень применения и внедрения в процесс разработки инструментов анализа кода может быть различным. Начиная от ручного запуска анализатора "время от времени" или при поиске трудноуловимых ошибок, и кончая ежедневным автоматическим запуском или запуском при добавлении нового исходного кода в систему контроля версий.
В статье рассмотрены различные уровни использования технологий статического анализа кода в командной разработке, показано как "перевести" процесс с одного уровня на другой. В качестве примера в статье используется разрабатываемый авторами анализатор кода PVS-Studio.
Реклама PVS-Studio - статический анализ кода на языке Си и Си++Andrey Karpov
Этот документ рекламирует статический анализатор PVS-Studio. Описывается, как использование PVS-Studio уменьшит количество ошибок в коде проекта на языке C/C++/C++11 и сократит затраты на тестирование, отладку и сопровождение кода. Приводится большое количество примеров ошибок, найденных анализатором в различных Open-Source проектах. Документ описывает PVS-Studio на момент версии 4.38 от 12 октября 2011 и, как следствие, не отражает возможности следующих версий. Чтобы познакомиться с новыми возможностями, предлагаем посетить сайт продукта <a>http://www.viva64.com</a> или поискать обновленный вариант этой статьи.
Интервью с Дмитрием Вьюковым – автором верификатора Relacy Race Detector (RRD)Tatyanazaxarova
Интервью с Дмитрием Вьюковым - автором инструмента Relacy Race Detector (RRD) для верификации параллельных приложений. В статье вы узнаете об истории создания RRD, его основных возможностях, а также о некоторых других аналогичных инструментах и их отличии от RRD.
Получасовая презентация по Java 9. Конечно, рассказать можно много больше, да и часть выводов прозизносил вслух, но в любом случае, если интересна Java 9, то изучение можно начать со ссылок в конце презентации.
Критика, предложения приветствуются.
На встрече мы поговорим о том, как не бояться изменений и как быть к ним готовым. Дадим определение АОП. Рассмотрим проблемы, хорошо решаемые инструментами АОП. Построим модульную систему, применяя АОП. Сравним динамический и статический подходы в АОП. Дадим рекомендации по применению АОП.
Вас ждет река теории впадающая в море практики.
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...yaevents
Александр Петренко, ИСП РАН
Профессор, доктор физико-математических наук, заведующий отделом технологий программирования Института системного программирования (ИСП РАН), профессор ВМК МГУ. Основные работы в областях: формализация требований, генерация тестов на основе формализованных требований и формальных моделей (model based testing – MBT). Приложения: тестирование операционных систем и распределенных систем, тестирование компиляторов, верификация дизайна микропроцессоров, формализация стандартов на API операционных систем и телекоммуникационных протоколов. Сопредседатель оргкомитетов International MBT workshop (http://www.mbrworkshop.org/), Spring Young Researcher Colloquium on Software Engineering – SYRCoSE (http://syrocose.ispras.ru), городского семинара по технологиям разработки и анализа программ ТРАП/SDAT (http://sdat.ispras.ru/).
Тема доклада
Модели в профессиональной инженерии и тестировании программ.
Тезисы
Model Based Software Engineering (MBSE) является расширением подхода к разработке программ на основе моделей. В MBSE в отличие, например, от MDA (Model Driver Architecture) существенное внимание уделяется не только задачам собственно проектирования и разработки кода, но и задачам других фаз жизненного цикла – анализу требований, верификации и валидации, управлению требованиями на всех фазах жизненного цикла. Model Based Testing (MBT) хронологически возник гораздо раньше, чем MBSE и MDA, однако его место в разработке программ в полной мере раскрылось вместе с развитием MBSE. По этой причине MBT и MBSE следует рассматривать в тесной связке. В докладе будут рассмотрены концепции MBSE-MDA-MBT, основные источники и виды моделей, которые используются в этих подходах, методы генерации тестов на основе моделей, известные инструменты для
СОВМЕСТНОЕ ПРИМЕНЕНИЕ КОНТРАКТОВ И ВЕРИФИКАЦИИ ДЛЯ ПОВЫШЕНИЯ КАЧЕСТВА АВТОМАТ...ITMO University
При создании систем со сложным поведением важную роль играет контроль качества разрабатываемых программ. Цена ошибки в таких системах может быть слишком велика, поэтому важно не просто проверить соответствие создаваемой программы всем предъявленным к ней требованиям, но и сделать этот процесс эффективным, максимально автоматизировав его. На практике этого можно добиться, формализовав все требования к программе и храня полученную исполнимую спецификацию непосредственно вместе с кодом программы. Рассмотрены существующие методы контроля качества современных программных систем и автоматных программ, а также описан процесс создания среды, позволяющей поддержать сразу три подхода к проверке качества программ с явным выделением состояний: проверку на модели, модульное тестирование и контракты. Предложенный подход позволяет сохранить корректность записи сформулированных требований при изменении самой программы, а также интерактивно контролировать ее качество.
Специфика разработки и тестирования статического анализатораAndrey Karpov
В докладе я расскажу об особенностях разработки и тестирования такого программного продукта, как статический анализатор. Опишу как стандартные методики тестирования, которые мы используем (обзоры кода, Unit и UI-тесты, нагрузочное тестирование), так и специфические, позволяющие контролировать качество поиска ошибок при внесении доработок в ядро анализатора.
Использование анализатора PVS-Studio в процессе инкрементальной сборки в Micr...Tatyanazaxarova
Одним из нововведений в последних версиях MSBuild/Visual Studio для компиляторов Visual C++ стала новая система минимальной сборки (также известная как инкрементная сборка), основанная на отслеживании зависимостей между входными и выходными данными при работе компилятора и позволяющая осуществлять пересборку только для файлов, затронутых модификацией исходного кода или не имеющих связанных с ними выходных объектных файлов. В отличие от старой методики минимальной пересборки, завязанной на генерируемые компилятором cl.exe файлы состояний (idb-файлы, Minimal Rebuild Dependancy Database, ключ /Gm) и обладавшей рядом недостатков (как например затруднённость распараллеливания сборки из-за конфликтов доступа и отсутствие прямого отслеживания выходных объектный файлов), новая система не зависит от типа используемых сборочных инструментов (может использоваться как для компиляции, так и для линковки) и имеет открытый API. Данная новинка позволила интегрировать проверку кода анализатором PVS-Studio в процесс разработки на C/C++ с использованием инкрементных пересборок для последней версии Visual Studio 2010. Эта возможность появилась в версии PVS-Studio 4.30.
Этюды о буферизации: асинхронные оповещения, репликация обновлений, объединен...corehard_by
Практика разработки конкретного приложения может приводить к постановке задачи, которая, в зрелом размышлении, оказывается достаточно общей, чтобы вычленить её в абстракцию, потенциально полезную для множества различных приложений. Приведение решения к виду, пригодному для многократного применения, в отличие от решения, отвечающего нуждам конкретного приложения, требует дополнительных мыслительных усилий по выделению вариативных аспектов задачи, и по их моделированию средствами языка. В докладе представлен опыт реализации трёх абстракций, объединенных общей темой — буферизацией данных при многопоточной обработке. Показан ход мысли от анализа задачи до реализации средствами языка C++17.
Сам по себе рост размера структур не является ошибкой, но может приводить к потреблению необоснованного количества памяти и в результате к замедлению скорости работы программы. Будем рассматривать данный паттерн не как ошибку, но как причину неэффективности 64-битного кода.
Процессоры работают эффективнее, когда имеют дело с правильно выровненными данными. А некоторые процессоры вообще не умеют работать с не выровненными данными.
Урок 25. Практическое знакомство с паттернами 64-битных ошибокTatyanazaxarova
Данная статья содержит различные примеры 64-битных ошибок, собранные в демонстрационном примере PortSample. Однако, начиная с версии PVS-Studio 3.63, вместо PortSample в дистрибутив PVS-Studio включается более новая версия примеров, которая называется OmniSample. Поэтому некоторые скриншоты в статье не соответствуют актуальному состоянию дел.
Мы закончили рассмотрение паттернов 64-битных ошибок. Последнее на чем мы остановимся в связи с этими ошибками, является то, как они могут проявляться в программах.
После компиляции программы в 64-битном режиме она начинает потреблять большее количество памяти, чем ее 32-битный вариант. Часто это увеличение почти незаметно, но иногда потребление памяти может возрастать в 2 раза.
Генерирование и обработка исключений с участием целочисленных типов не является хорошей практикой программирования на языке Си++. Для этих целей следует использовать более информативные типы, например классы, производные от класса std::exception.
Урок 27. Особенности создания инсталляторов для 64-битного окруженияTatyanazaxarova
При разработке 64-битной версии приложения дополнительное внимание стоит уделить и вопросу дистрибуции программы. Ведь при установке на 64-битной операционной системе есть несколько нюансов, забыв о которых можно получить неработающий инсталляционный пакет.
VivaMP, система выявления ошибок в коде параллельных программ на языке С++, и...Tatyanazaxarova
В статье приводятся результаты исследований ошибок, которые допускают программисты, использующие С++ и OpenMP. Для автоматического обнаружения этих ошибок предлагается использование статического анализа. Описывается интегрирующийся в среду Visual Studio анализатор VivaMP, реализующий поставленную задачу.
В работе приведен обзор 7 классов метрик и более 50 их представителей, дано детальное описание и используемые алгоритмы вычисления, описана роль метрик в разработке программного обеспечения.
Построение систем автоматического протоколирования Си/Си++ кодаTatyanazaxarova
Иногда единственным методом отладки является использование протоколирования событий приложения. К недостаткам протоколирования (логирования) можно отнести большой объем кода, который приходится писать вручную для сохранения всей необходимой информации. В статье рассматривается методика, позволяющая построить систему автоматического протоколирования кода на языке Си/Си++.
В статье описаны технологии тестирования, используемые при разработке статического анализатора кода PVS-Studio. Разработчики инструмента для программистов делятся принциами тестирования собственного программного продукта, которые могут быть интересны разработчикам аналогичных пакетов обработки текстовых данных или исходных кодов.
Статический анализ кода для верификации 64-битных приложенийTatyanazaxarova
В результате появления на рынке персональных компьютеров 64-битных процессоров, перед разработчиками программ возникает задача переноса старых 32-битных приложений на новую платформу. После такого переноса кода приложение может вести себя некорректно. В статье рассматривается вопрос разработки и применения статического анализатора кода для проверки правильности таких приложений. Приводятся проблемы, возникающие в приложениях после перекомпиляции для 64-битных систем, а также правила, по которым выполняется проверка кода.
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...Tatyanazaxarova
В результате появления на рынке персональных компьютеров 64-битных процессоров перед разработчиками программ возникает задача переноса старых 32-битных приложений на новую платформу. После переноса кода приложения высока вероятность его некорректной работы. В статье рассмотрены вопросы, связанные с верификацией и тестированием программного обеспечения. Обозначены сложности, с которыми может столкнуться разработчик 64-битных Windows приложений и пути их преодоления.
основы ооп на языке C#. часть 1. введение в программированиеYakubovichDA
Основы объектно-ориентированного программирования на языке C#. Часть 1. Введение в программирование.
Рассматривается базовые понятие алгоритмов, блок-схем, объектно-ориентированного программирования на базе платформы .NET Framework.
Облегчаем процесс разработки с помощью статического анализа кода: Наш опытAndrey Karpov
Статический анализ кода является очень полезным DevOps-средством, помогающим программистам при разработке крупных (и не только) проектов. К сожалению, с ним знакомы далеко не все программисты, а те, кто знаком — часто вспоминают их как «старые добрые lint'еры».
В своем докладе автор покажет, на что на самом деле способен современный статический анализ, а также расскажет о опыте внедрения анализатора в процесс разработки Unreal Engine 4.
Доклад будет полезен программистам всех уровней, руководителям, а также DevOps-специалистам, желающим повысить качество их проектов.
Разница в подходах анализа кода компилятором и выделенным инструментомTatyanazaxarova
У компилятора и сторонних инструментов статического анализа кода есть общая задача - выявление опасных фрагментов кода. Однако существует существенная разница в том, анализ какого типа они осуществляют. Я попробую на примере компилятора Intel C++ и анализатора PVS-Studio продемонстрировать различия подходов, и пояснить, чем они вызваны.
Урок 19. Паттерн 11. Сериализация и обмен даннымиTatyanazaxarova
Важным элементом переноса программного решения на новую платформу является преемственность к существующим протоколам обмена данными. Необходимо обеспечить чтение существующих форматов проектов, осуществлять обмен данными между 32-битными и 64-битными процессами и так далее.
Надеемся, вы уже успели отдохнуть от 13 урока и теперь сможете рассмотреть еще один важный паттерн ошибок, связанный с арифметическими выражениями, в которых участвуют типы различной размерности.
Урок 16. Паттерн 8. Memsize-типы в объединенияхTatyanazaxarova
Особенностью объединения (union) является то, что для всех элементов (членов) объединения выделяется одна и та же область памяти, то есть они перекрываются. Хотя доступ к этой области памяти возможен с использованием любого из элементов, элемент для этой цели должен выбираться так, чтобы полученный результат был осмысленным.
Большое количество ошибок при миграции на 64-битные системы связано с изменением соотношения между размером указателя и размером обычных целых. В среде с моделью данных ILP32 обычные целые и указатели имеют одинаковый размер. К сожалению, 32-битный код повсеместно опирается на это предположение. Указатели часто приводятся к int, unsigned, long, DWORD и другим неподходящим типам.
Мы специально выбрали номер "тринадцать" для этого урока, поскольку ошибки, связанные с адресной арифметикой в 64-битных системах, являются наиболее коварными. Надеемся, число 13 заставит вас быть внимательнее.
Урок 10. Паттерн 2. Функции с переменным количеством аргументовTatyanazaxarova
Классическими примерами, приводимыми во многих статьях по проблемам переноса программ на 64-битные системы, является некорректное использование функций printf, scanf и их разновидностей.
В некачественном коде часто встречаются магические числовые константы, наличие которых опасно само по себе. При миграции кода на 64-битную платформу эти константы могут сделать код неработоспособным, если участвуют в операциях вычисления адреса, размера объектов или в битовых операциях.
Урок 8. Статический анализ для выявления 64-битных ошибокTatyanazaxarova
Статический анализ кода - методология выявления ошибок в программном коде, основанная на просмотре программистом участков кода, помеченных статическим анализатором. Помеченные участки кода с большой вероятностью содержат ошибки определенного типа.
Исправление всех ошибок компиляции и предупреждений не будет означать работоспособность 64-битного приложения. И именно описанию и диагностике 64-битных ошибок будет посвящена основная часть уроков. Также не надейтесь на помощь ключа /Wp64, который многими часто без оснований преподносится при обсуждениях в форумах как чудесное средство поиска 64-битных ошибок.
Хочется сразу предупредить читателя, что невозможно всесторонне описать процесс сборки 64-битного приложения. Настройки любого проекта достаточно уникальны, поэтому к адаптации настроек для 64-битной системы всегда надо подходить внимательно. В уроке будут описаны только общие шаги, которые важны для любого проекта. Эти шаги подскажут вам с чего начать процесс.
Вначале следует убедиться, что используемая вами редакция Visual Studio позволяет собирать 64-битный код. Если вы планируете разрабатывать 64-битные приложения с использованием последней версии (на момент написания курса) Visual Studio 2008, то следующая таблица поможет определить, какая из редакций Visual Studio вам необходима.
PVS-Studio, решение для разработки современных ресурсоемких приложенийTatyanazaxarova
Инструмент PVS-Studio
набор правил Viva64 для анализа 64-битных приложений;
набор правил VivaMP для анализа параллельных приложений;
набор правил для анализа общего назначения.
Лицензионная и ценовая политика PVS-Studio
Информация о компании ООО «СиПроВер»
Мы все допускаем ошибки при программировании и тратим массу времени на их устранение.
Один из методов который позволяет быстро диагностировать дефекты – статический анализ исходного кода.
PVS-Studio - статический анализатор, выявляющий ошибки в исходном коде приложений на языке C/C++/C++0x. Можно выделить 3 набора правил, включенных в состав PVS-Studio:
1. Диагностика 64-битных ошибок (Viva64)
2. Диагностика параллельных ошибок (VivaMP)
3. Диагностика общего назначения
PVS-Studio научился следить за тем, как вы программируетеTatyanazaxarova
В PVS-Studio появился режим работы, который поможет максимально рано выявлять ошибки и опечатки. Анализатор запускается сразу после компиляции файлов и если что-то не так, покраснеет от стыда за ваш код. Фича доступна на данный момент только для пользователей Visual Studio 2010.
Многим читателя понравилась моя статья "Последствия использования технологии Copy-Paste при программировании на Си++ и как с этим быть" [1]. Обратил на неё внимание и Scott Meyers [2] и задал вопрос о том, как же собственно статический анализ помог выявить описанные в статье ошибки.
Я регулярно общаюсь с потенциальными пользователями, озабоченными ошибками в программах на языке Си++. Их озабоченность выражается в том, что они пробуют инструмент PVS-Studio и начинают писать о том, что при испытаниях что-то подозрительно мало ошибок было найдено. И хотя, вроде чувствуется, что инструмент им интересен, их реакция полна скептицизма.
Казалось, закончились долгие обсуждения в форумах, как измерить время работы алгоритма, какие функции использовать, какую точность ожидать. Жаль, но опять придется вернуться к этому вопросу. На повестке дня вопрос – как лучше измерить скорость работы параллельного алгоритма.
Отладка и оптимизация многопоточных OpenMP-программ
1. Отладка и оптимизация
многопоточных OpenMP-программ
Авторы: Андрей Карпов, Евгений Романовский
Дата: 24.01.2009
Аннотация
Задача знакомства программистов с областью разработки параллельных приложений становится
все актуальней. Данная статья является кратким введением в создание многопоточных
приложений, основанных на технологии OpenMP. Описаны подходы к отладке и оптимизации
параллельных приложений.
В предложенной статье рассматривается технология OpenMP, главная ценность которой в
возможности доработки и оптимизации уже созданного последовательного кода. Стандарт
OpenMP предоставляет собой набор спецификаций для распараллеливания кода в среде с общей
памятью. Ключевое условие для использования OpenMP - поддержка этого стандарта со стороны
компилятора. Кроме того, требуются принципиально новые инструменты для этапа отладки, на
котором обнаруживаются, локализуются и устраняются ошибки, и производится оптимизация.
Отладчик для последовательного кода это хорошо знакомый и активно используемый
программистом инструмент. Он предоставляет разработчику возможность отслеживать
изменения значений переменных при пошаговом выполнении программы с помощью развитого
пользовательского интерфейса. Однако ситуация значительно меняется, когда заходит речь об
отладке и тестировании многопоточных приложений. А именно создание многопоточных
приложений становится основным направлением в создании эффективных приложений.
Отладка последовательной программы основана на том, что степень предсказуемости начального
и текущего состояний программы определяется входными данными. Когда программист
переходит к отладке многопоточного кода, то он обычно сталкивается с совершенно уникальными
проблемами: в различных операционных системах применяются разные стратегии планирования,
нагрузка на вычислительную систему динамически изменяется, приоритеты процессов могут
различаться и т. д. Точное воссоздание состояния программы в некоторый момент ее выполнения
(тривиальная задача для последовательной отладки) значительно усложняется при переходе к
параллельной программе, что связано с недетерминированным поведением последней. Иными
словами, поведение запущенных в системе процессов, а именно их выполнение и ожидание
выполнения, взаимные блокировки и прочее, зависит от случайных событий, происходящих в
системе. Как же быть? Очевидно, для отладки параллельного кода требуются совершенно другие
средства.
По мере того, как параллельные вычислительные системы стали обычным явлением в
потребительском сегменте рынка, спрос на средства отладки многопоточных приложений
существенно увеличился. Мы рассмотрим отладку и повышение производительности
многопоточного приложения, построенного на основе технологии OpenMP. Полный текст
программы, из которого мы будем приводить отдельные участки кода содержится в конце статьи
в приложении N1.
2. Для примера возьмем последовательный программный код функции Function, приведенный в
листинге 1. Эта простая подпрограмма вычисляет значения некоторой математической функции,
имеющей один аргумент.
double Function(int N)
{
double x, y, s=0;
for (int i=1; i<=N; i++) {
x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
s += j * y;
y = y * x;
};
};
return s;
}
При вызове этой функции с аргументом N, равным 15000, мы получим резуьтат 287305025.528.
Эту функцию можно легко распараллелить с помощью средств стандарта OpenMP. Добавим одну
единственную строку перед первым оператором for (листинг 2).
double FunctionOpenMP(int N)
{
double x, y, s=0;
#pragma omp parallel for num_threads(2)
for (int i=1; i<=N; i++) {
x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
s += j * y;
y = y * x;
};
};
3. return s;
}
К сожалению, созданный нами код является некорректным и результат работы функции в общем
случае не определен. Например, он может быть равен 298441282.231. Попробуем разобраться в
причинах.
Основная причина ошибок в параллельных программах — некорректная работа с разделяемыми,
т. е. общими для всех запущенных процессов ресурсами, в частном случае — с общими
переменными.
Данная программа успешно компилируется в среде Microsoft Visual Studio 2005, причем
компилятор даже не выдает никаких предупреждений. Однако она некорректна. Чтобы это
понять, надо вспомнить, что в OpenMP-программах переменные делятся на общие (shared),
существующие в одном экземпляре и доступные всем потокам, и частные (private),
локализованные в конкретном процессе. Кроме того, есть правило, гласящее, что по умолчанию
все переменные в параллельных регионах OpenMP общие, за исключением индексов
параллельных циклов и переменных, объявленных внутри этих параллельных регионов.
В приведенном выше примере видно, что переменные x, y и s — общие, что совершенно
неправильно. Переменная s обязательно должна быть общей, так как в рассматриваемом
алгоритме она является, по сути, сумматором. Однако при работе с переменными x или y каждый
процесс вычисляет очередное их значение и записывает в соответствующую переменную (x или
y). И тогда результат вычислений зависит от того, в какой последовательности выполнялись
параллельные потоки. Иначе говоря, если первый поток вычислит значение для x, запишет его в
переменную x, а потом такие же действия произведет второй поток, то при попытке прочитать
значение переменной x первым потоком он получит то значение, которые было записано туда
последним по времени, а значит, вычисленное вторым потоком. Подобные ошибки в случае,
когда работа программы зависит от порядка выполнения различных фрагментов кода,
называются race condition или data race (состояние "гонки" или "гонки" вычислительных потоков;
подразумевается, что имеют место несинхронизированные обращения к памяти).
Для поиска таких ошибок необходимы специальные программные средства. Одно из них - Intel
Thread Checker. Адрес продукта: http://www.viva64.com/go.php?url=526. Данная программа
поставляется как модуль к профилировщику Intel VTune Performance Analyzer, дополняя
имеющиеся средства для работы с многопоточным кодом. Intel Thread Checker позволяет
обнаружить как описанные выше ошибки, так и многие другие, например deadlocks ("тупики",
места взаимной блокировки вычислительных нитей) и утечки памяти.
После установки Intel Thread Checker в диалоге New Project приложения Intel VTune Performance
Analyzer появится новая категория проектов — Threading Wizards (мастера для работы с потоками),
среди которых будет Intel Thread Checker Wizard. Для запуска примера необходимо выбрать его, а
в следующем окне мастера указать путь к запускаемой программе. После запуска программа
начнет выполняться, а профилировщик соберет все сведения о работе приложения. Пример такой
информации, выдаваемой Intel Thread Checker, приведен на рисунке 1.
4.
5. Рисунок 1 - В результате работы Thread Checker обнаружено множество критических ошибок
Как видно, даже для такой небольшой программы количество ошибок достаточно велико. Thread
Checker группирует обнаруженные ошибки, одновременно оценивая их критичность для работы
программы, и приводит их описание, что существенно повышает эффективность работы
программиста. Кроме того, на вкладке Source View представлен программный код приложения с
указанием тех мест в коде, где имеются ошибки (рисунок 2).
6.
7. Рисунок 2 - Анализ многопоточного кода Intel Thread Checker
Следует учитывать, что Intel Thread Checker в ряде случаях не может выявить ошибку. Это
относится к коду, который редко получает управление или выполняется на системе с другой
архитектурой. Ошибка также может быть пропущена, когда набор входных тестовых данных
сильно отличается от данных обрабатываемых программой при ее эксплуатации конечными
пользователями. Все это не позволяет быть уверенным в отсутствии ошибок в многопоточной
программе, после проверки ее с использованием динамических средств анализа, результат
которых зависит от среды и времени исполнения.
8. Но хорошей новостью для разработчиков OpenMP является существование и другого инструмента
- VivaMP, предлагающего альтернативный подход к верификации параллельных программ.
VivaMP построен по принципу статического анализатора кода и позволяет проверять код
приложения без его запуска. Более подробно с инструментом VivaMP можно познакомиться на
сайте разработчиков http://www.viva64.com/ru/vivamp-tool/.
Области применения VivaMP:
• Контроль корректности кода разрабатываемых приложений на базе технологии OpenMP.
• Помощь в освоении технологии OpenMP и интеграция ее в уже существующие проекты.
• Создание более эффективных в использовании ресурсов параллельных приложений.
• Поиск ошибок в существующих OpenMP приложениях.
Анализатор VivaMP интегрируется в среду Visual Studio 2005/2008 и предоставляет простой
интерфейс для проверки приложений (рисунок 3).
9. Рисунок 3 - Запуск инструмента VivaMP, интегрированного в Visual Studio 2005
VivaMP,
Если мы запустим VivaMP для нашего примера, то получим сообщение об ошибках в 4 различных
строках, где происходит некорректная модификация переменных (рисунок 4).
Рисунок 4 - Результат работы статического анализатора VivaMP
анализатора
Конечно, статический анализ также имеет ряд недостатков, как и динамический анализ. Но вместе
эти две методологии (два инструмента Intel Thread Checker и VivaMP) отлично дополнят друг
друга. И их совместное использование является достаточно надежным методом выявления
надежным
ошибок в многопоточных приложениях.
Описанную выше и обнаруженную средствами Intel Thread Checker и VivaMP ошибку записи в
переменные x и y исправить довольно просто: нужно лишь добавить в конструкцию #pragma omp
parallel for еще одну директиву private (x, y). Таким образом, эти две переменные будут
директиву:
объявлены как частные, и в каждом вычислительном потоке будут свои копии x и y. Следует также
обратить внимание, что все потоки сохраняют вычисленный результат добавлением его к
переменной s. Подобные ошибки происходят тогда, когда один вычислительный поток пытается
нной
записать некоторое значение в общую память, а другой в то же время выполняет операцию
чтения. В рассматриваемом примере это может привести к некорректному результату.
Рассмотрим инструкцию s += j*y. Изначально предполагается, что каждый поток суммирует
трим
вычисленный результат с текущим значением переменной s, а потом такие же действия
выполняют остальные потоки. Однако возможна ситуация, когда, например, два потока
одновременно начали выполнять инструкцию s += j*y, т. е. каждый из них сначала прочитает
текущее значение переменной s, затем прибавит к этому значению результат умножения j*y и
полученное запишет в общую переменную s.
В отличие от операции чтения, которая может быть реализована параллельно и является
достаточно быстрой, операция записи всегда последовательна. Следовательно, если сначала
10. первый поток записал новое значение, то второй поток, выполнив после этого запись, затрет
результат вычислений первого, потому что оба вычислительных потока сначала прочитали одно и
то же значение s, а потом стали записывать свои данные в эту переменную. Иными словами, то
значение s, которое второй поток в итоге запишет в общую память, никак не учитывает результат
вычислений, полученный в первом потоке. Можно избежать подобной ситуации, если
гарантировать, что в любой момент времени операцию s += j*y разрешается выполнять только
одному из потоков. Такие операции называются неделимыми или атомарными. Когда нужно
указать компилятору, что какая-либо инструкция является атомарной, используется конструкция
#pragma omp atomic. Программный код, в котором исправлены указанные ошибки, приведен в
листинге 3.
double FixedFunctionOpenMP(int N)
{
double x, y, s=0;
#pragma omp parallel for
private(x,y) num_threads(2)
for (int i=1; i<=N; i++) {
x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
#pragma omp atomic
s += j * y;
y = y * x;
};
};
return s;
}
После перекомпиляции программы и ее повторного анализа в Thread Checker мы увидим, что
программа не содержит критических ошибок. Выводятся только два информационных сообщения
о том, что параллельные потоки завершаются при достижении оператора return в функции
MathFunction. В рассматриваемом примере так и должно быть, потому что распараллеливается
только код внутри данной функции. Статический анализатор VivaMP не выдаст на этот код вообще
никаких диагностических сообщений, так как он полностью корректен с его точки зрения.
Но отдыхать еще рано. Давайте уточним, действительно ли наш код стал более эффективным
после распараллеливания. Замерим время выполнения трех функций: 1 - последовательной, 2 -
параллельной некорректной, 3 - параллельной корректной. Результаты такого измерения для
N=15000 приведены в таблице 1.
11. Функция Результат Время
выполнения
Последовательный вариант функции 287305025.528 0.5781 секунд
Некорректный вариант параллельной функции 298441282.231 2.9531 секунд
Корректный вариант параллельной функции, использующий 287305025.528 36.8281 секунд
директиву atomic
Таблица 1 - Результат работы функций
И что мы видим в таблице? А то, что параллельный вариант некорректной функции работает в
несколько раз медленнее. Но нас эта функция не интересует. Беда в том, что правильный вариант
работает вообще более чем в 60 раз медленнее. Нам нужна такая параллельность? Конечно, нет.
Все дело в том, что мы выбрали крайне неэффективный метод решения проблемы с
суммированием результата в переменной s, использованием директивы atomic. Такой подход
приводит к частому ожиданию потоками друг друга. Чтобы избежать постоянных взаимных
блокировок при выполнении атомарной операции суммирования мы можем использовать
специальную директиву reduction. Опция reduction определяет, что на выходе из параллельного
блока переменная получит комбинированное значение. Допустимы следующие операции: +, *, -,
&, |, ^, &&, ||. Модифицированный вариант функции показан в листинге 4.
double OptimizedFunction(int N)
{
double x, y, s=0;
#pragma omp parallel for private(x,y)
num_threads(2) reduction(+: s)
for (int i=1; i<=N; i++) {
x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
s += j * y;
y = y * x;
};
};
return s;
}
На этот мы получим не только корректный, но и более производительный вариант функции
(таблица 2). Скорость вычисления возросла почти в 2 раза (в 1.85 раз), что является очень
хорошим показателем для подобных функций.
Функция Результат Время
12. выполнения
Последовательный вариант функции 287305025.528 0.5781 секунд
Некорректный вариант параллельной функции 298441282.231 2.9531 секунд
Корректный вариант параллельной функции, использующий 287305025.528 36.8281 секунд
директиву atomic
Корректный вариант параллельной функции, использующий 287305025.528 0.3125 секунд
директиву reduction
Таблица 2 - Результат работы функций
В заключение еще раз хочется подчеркнуть, что работоспособная параллельная программа может
далеко не всегда являться эффективной. И хотя параллельное программирование предоставляет
множество способов повышения эффективности кода, оно требует от программиста
внимательности и хороших знаний используемых им технологий. К счастью существуют такие
инструменты, как Intel Thread Checker и VivaMP, существенно облегчающих создание и проверки
многопоточных приложений. Удачи вам уважаемые читатели в освоении новой области знаний.
Приложение N1. Текст демонстрационной программы
#include "stdafx.h"
#include <omp.h>
#include <stdlib.h>
#include <windows.h>
class VivaMeteringTimeStruct {
public:
VivaMeteringTimeStruct()
{ m_userTime = GetCurrentUserTime(); }
~VivaMeteringTimeStruct()
{ printf("Time = %.4f secondsn", GetUserSeconds()); }
double GetUserSeconds();
private:
__int64 GetCurrentUserTime() const;
__int64 m_userTime;
};
__int64 VivaMeteringTimeStruct::GetCurrentUserTime() const
{
FILETIME creationTime, exitTime, kernelTime, userTime;
GetThreadTimes(GetCurrentThread(), &creationTime,
13. &exitTime, &kernelTime, &userTime);
__int64 curTime;
curTime = userTime.dwHighDateTime;
curTime <<= 32;
curTime += userTime.dwLowDateTime;
return curTime;
}
double VivaMeteringTimeStruct::GetUserSeconds()
{
__int64 delta = GetCurrentUserTime() - m_userTime;
return double(delta) / 10000000.0;
}
double Function(int N)
{
double x, y, s=0;
for (int i=1; i<=N; i++) {
x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
s += j * y;
y = y * x;
};
};
return s;
}
double FunctionOpenMP(int N)
{
double x, y, s=0;
#pragma omp parallel for num_threads(2)
for (int i=1; i<=N; i++) {
14. x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
s += j * y;
y = y * x;
};
};
return s;
}
double FixedFunctionOpenMP(int N)
{
double x, y, s=0;
#pragma omp parallel for private(x,y) num_threads(2)
for (int i=1; i<=N; i++) {
x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
#pragma omp atomic
s += j * y;
y = y * x;
};
};
return s;
}
double OptimizedFunction(int N)
{
double x, y, s=0;
#pragma omp parallel for private(x,y)
num_threads(2) reduction(+: s)
for (int i=1; i<=N; i++) {
15. x = (double)i/N;
y = x;
for (int j=1; j<=N; j++) {
s += j * y;
y = y * x;
};
};
return s;
}
int _tmain(int , _TCHAR* [])
{
int N = 15000;
{
VivaMeteringTimeStruct Timer;
printf("Result = %.3f ", Function(N));
}
{
VivaMeteringTimeStruct Timer;
printf("Result = %.3f ", FunctionOpenMP(N));
}
{
VivaMeteringTimeStruct Timer;
printf("Result = %.3f ", FixedFunctionOpenMP(N));
}
{
VivaMeteringTimeStruct Timer;
printf("Result = %.3f ", OptimizedFunction(N));
}
return 0;
}