[C++, Системы сборки] Опыт команды PVS-Studio: повышение производительности C++ анализатора на Windows при переходе на Clang
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
С самого своего начала C++ анализатор PVS-Studio для Windows (тогда еще Viva64 версии 1.00 в 2006 году) собирался компилятором MSVC. С выходом новых релизов C++ ядро анализатора научилось работать на Linux и macOS, и структура проекта была переведена на использование CMake. Но под Windows сборка по-прежнему происходила с помощью компилятора MSVC. 29 апреля 2019 года разработчики Visual Studio объявили о включении в свою среду разработки набора утилит LLVM и компилятора Clang. И сейчас у нас наконец дошли руки, чтобы попробовать его в действии.
Тестирование производительностиВ качестве бенчмарка воспользуемся нашей утилитой для регрессионного тестирования анализатора под названием SelfTester. Суть её работы заключается в анализе набора разных проектов и сравнении результатов анализа с эталонными. Например, если при каких-то правках в ядре анализатора появились ложные предупреждения или пропали правильные, значит появилась регрессия, которую надо исправить. Более подробно про SelfTester можно прочитать в статье "Лучшее – враг хорошего".Среди тестовой базы – достаточно разнообразные по объёму кода проекты. Как правило, если рабочий компьютер или тестовый сервер не нагружен, то время тестирования SelfTester'ом на одной и той же версии ядра варьируется в пределах погрешности. В случае если производительность анализатора не уберегли, это значительно скажется на общем времени тестирования.После того как сборка C++ ядра перешла на Clang, SelfTester стал проходить на 11 минут быстрее.
Выигрыш по производительности в 13% — это довольно заметно, учитывая, что достаточно просто поменять компилятор, не так ли?Минусы тоже есть, но незначительные. Сборка дистрибутива замедлилась на 8 минут, а размер исполняемого файла подрос на 1,6 Мбайт (из них ~500 Кбайт из-за статической линковки рантайма).
Видимо, производительность достигается более долгим этапом LTO (большую часть сборки занимает именно линковка) и более агрессивным раскручиванием циклов и встраиванием функций.Далее хочется поделиться подводными камнями, возникшими в процессе перехода.Генерация сборки под ClangСкрипты CMake позволяют нам собирать свой код всеми мейнстримными компиляторами под нужные операционные системы.Прежде всего необходимо установить компоненты компилятора Clang через Visual Studio Installer.
Clang-cl — это так называемый "драйвер", который позволяет использовать clang с параметрами от cl.exe. Таким образом, он должен прозрачно взаимодействовать с MSBuild, практически как родной компилятор.Также можно воспользоваться официальными сборками от проекта LLVM, которые можно найти на их репозитории GitHub. Однако для них нужно установить дополнительный плагин, чтобы Visual Studio смогла найти компиляторы. Имя toolset'а будет llvm, а не clangcl, как показано дальше в примерах.Указываем toolchain в команде генерации solution для Visual Studio:
cmake -G "Visual Studio 16 2019" -Tclangcl <src>
Либо используем GUI:
Открываем получившийся проект, собираем. И, конечно же, получаем пачку ошибок.
Чиним сборкуХоть сlang-cl внешне и ведет себя как CL, под капотом это совсем другой компилятор, со своими приколами.Мы стараемся не игнорировать предупреждения компиляторов, поэтому используем флаги /W4 и /WX. Однако Clang может генерировать дополнительные предупреждения, которые сейчас мешают сборке. Пока выключим их:
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
....
if (WIN32)
add_compile_options(-Wno-error=deprecated-declarations
-Wno-error=reorder-ctor
-Wno-error=format-security
-Wno-error=macro-redefined
-Wno-error=bitwise-op-parentheses
-Wno-error=missing-field-initializers
-Wno-error=overloaded-virtual
-Wno-error=invalid-source-encoding
-Wno-error=multichar
-Wno-unused-local-typedef
-Wno-c++11-narrowing)
....
endif()
endif()
Немного получше.Компиляторы GCC и Clang имеют встроенную поддержку типа int128, в отличие от MSVC под Windows. Поэтому в своё время была написана обертка с реализацией Int128 для Windows (на ассемблерных вставках и обернутая ifdef'ами, в лучших традициях C/C++). Поправим определения для препроцессора, заменив:
if (MSVC)
set(DEFAULT_INT128_ASM ON)
else ()
set(DEFAULT_INT128_ASM OFF)
endif ()
на
if (MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(DEFAULT_INT128_ASM ON)
else ()
set(DEFAULT_INT128_ASM OFF)
endif ()
Обычно библиотеку с builtin'ами линкеру (lld) передает драйвер компилятора, будь то clang.exe или clang-cl.exe. Но в данном случае линкером заправляет MSBuild напрямую, который не знает, что нужно её использовать. Соответственно, драйвер никак не может передать флаги линкеру, поэтому приходится разбираться самим.
if (CMAKE_GENERATOR MATCHES "Visual Studio")
link_libraries("$(LLVMInstallDir)\\lib\\clang\\\
${CMAKE_CXX_COMPILER_VERSION}\\lib\\windows\\\
clang_rt.builtins-x86_64.lib")
else()
link_libraries(clang_rt.builtins-x86_64)
endif()
Ура! Сборка заработала. Однако дальше при запуске тестов нас ждала куча ошибок сегментации:
Отладчик при этом показывает какое-то странное значение в IntegerInterval, а на самом деле проблема находится немного дальше:
В разных структурах для Dataflow-механизма активно применяется ранее упомянутый тип Int128, а для работы с ним используются SIMD-инструкции. И падение вызвано невыровненным адресом:
Инструкция MOVAPS перемещает из памяти набор чисел с плавающей запятой в регистры для SIMD-операций. Адрес при этом обязан быть выровнен, в его конце должен стоять 0, а оказалась 8. Придется помочь компилятору, задав правильное выравнивание:
class alignas(16) Int128
Порядок.Последняя проблема вылезла из-за Docker-контейнеров:
Сборка под MSVC всегда делалась со статической линковкой рантайма, а для экспериментов с Clang рантайм переключили на динамический. Оказалось, что в образах с Windows по умолчанию не установлены Microsoft Visual C++ Redistributable. Решили вернуть статическую линковку, чтобы у пользователей не возникало таких же неприятностей.ЗаключениеНесмотря на то, что пришлось немного повозиться с подготовкой проекта, мы остались довольны ростом производительности анализатора более чем на 10%.Последующие релизы PVS-Studio на Windows будут собираться с помощью компилятора Clang.Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Alexey Govorov, Sergey Larin. PVS-Studio Team: Switching to Clang Improved PVS-Studio C++ Analyzer's Performance.
===========
Источник:
habr.com
===========
Похожие новости:
- [C++, Программирование микроконтроллеров] Stm32 + USB на шаблонах C++. Продолжение. Делаем CDC
- [Программирование, C++] Как компилятор C++ находит правельную функцию (перевод)
- [Управление разработкой, Системы сборки, Управление проектами, Управление продуктом] Теперь YouTrack интегрируется с GitLab CI/CD
- [Программирование, C++] Худшие места в C++ для написания кода
- [Git, Системы управления версиями, Системы сборки, DevOps] Приглашаем на Yalantis Software Architecture Conference
- [Информационная безопасность, Программирование, C++] Грехи C++ (перевод)
- [Open source, Программирование, C++] Развитие проекта arataga: пара рефакторингов по результатам натурных испытаний
- [C++, GTK+] Gtk, OpenGL и все-все-все
- [C++, C] На собеседовании: Почему не пишут ядро ОС на C++? Немного про Fuchsia и Zircon
- [C++, Визуализация данных, Разработка под Windows] Ещё один модуль рисования графиков
Теги для поиска: #_c++, #_sistemy_sborki (Системы сборки), #_pvsstudio, #_clang, #_cmake, #_sborka_proekta (сборка проекта), #_benchmarking (бенчмаркинг), #_blog_kompanii_pvsstudio (
Блог компании PVS-Studio
), #_c++, #_sistemy_sborki (
Системы сборки
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:35
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
С самого своего начала C++ анализатор PVS-Studio для Windows (тогда еще Viva64 версии 1.00 в 2006 году) собирался компилятором MSVC. С выходом новых релизов C++ ядро анализатора научилось работать на Linux и macOS, и структура проекта была переведена на использование CMake. Но под Windows сборка по-прежнему происходила с помощью компилятора MSVC. 29 апреля 2019 года разработчики Visual Studio объявили о включении в свою среду разработки набора утилит LLVM и компилятора Clang. И сейчас у нас наконец дошли руки, чтобы попробовать его в действии. Тестирование производительностиВ качестве бенчмарка воспользуемся нашей утилитой для регрессионного тестирования анализатора под названием SelfTester. Суть её работы заключается в анализе набора разных проектов и сравнении результатов анализа с эталонными. Например, если при каких-то правках в ядре анализатора появились ложные предупреждения или пропали правильные, значит появилась регрессия, которую надо исправить. Более подробно про SelfTester можно прочитать в статье "Лучшее – враг хорошего".Среди тестовой базы – достаточно разнообразные по объёму кода проекты. Как правило, если рабочий компьютер или тестовый сервер не нагружен, то время тестирования SelfTester'ом на одной и той же версии ядра варьируется в пределах погрешности. В случае если производительность анализатора не уберегли, это значительно скажется на общем времени тестирования.После того как сборка C++ ядра перешла на Clang, SelfTester стал проходить на 11 минут быстрее. Выигрыш по производительности в 13% — это довольно заметно, учитывая, что достаточно просто поменять компилятор, не так ли?Минусы тоже есть, но незначительные. Сборка дистрибутива замедлилась на 8 минут, а размер исполняемого файла подрос на 1,6 Мбайт (из них ~500 Кбайт из-за статической линковки рантайма). Видимо, производительность достигается более долгим этапом LTO (большую часть сборки занимает именно линковка) и более агрессивным раскручиванием циклов и встраиванием функций.Далее хочется поделиться подводными камнями, возникшими в процессе перехода.Генерация сборки под ClangСкрипты CMake позволяют нам собирать свой код всеми мейнстримными компиляторами под нужные операционные системы.Прежде всего необходимо установить компоненты компилятора Clang через Visual Studio Installer. Clang-cl — это так называемый "драйвер", который позволяет использовать clang с параметрами от cl.exe. Таким образом, он должен прозрачно взаимодействовать с MSBuild, практически как родной компилятор.Также можно воспользоваться официальными сборками от проекта LLVM, которые можно найти на их репозитории GitHub. Однако для них нужно установить дополнительный плагин, чтобы Visual Studio смогла найти компиляторы. Имя toolset'а будет llvm, а не clangcl, как показано дальше в примерах.Указываем toolchain в команде генерации solution для Visual Studio: cmake -G "Visual Studio 16 2019" -Tclangcl <src>
Открываем получившийся проект, собираем. И, конечно же, получаем пачку ошибок. Чиним сборкуХоть сlang-cl внешне и ведет себя как CL, под капотом это совсем другой компилятор, со своими приколами.Мы стараемся не игнорировать предупреждения компиляторов, поэтому используем флаги /W4 и /WX. Однако Clang может генерировать дополнительные предупреждения, которые сейчас мешают сборке. Пока выключим их: if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
.... if (WIN32) add_compile_options(-Wno-error=deprecated-declarations -Wno-error=reorder-ctor -Wno-error=format-security -Wno-error=macro-redefined -Wno-error=bitwise-op-parentheses -Wno-error=missing-field-initializers -Wno-error=overloaded-virtual -Wno-error=invalid-source-encoding -Wno-error=multichar -Wno-unused-local-typedef -Wno-c++11-narrowing) .... endif() endif() Немного получше.Компиляторы GCC и Clang имеют встроенную поддержку типа int128, в отличие от MSVC под Windows. Поэтому в своё время была написана обертка с реализацией Int128 для Windows (на ассемблерных вставках и обернутая ifdef'ами, в лучших традициях C/C++). Поправим определения для препроцессора, заменив: if (MSVC)
set(DEFAULT_INT128_ASM ON) else () set(DEFAULT_INT128_ASM OFF) endif () if (MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(DEFAULT_INT128_ASM ON) else () set(DEFAULT_INT128_ASM OFF) endif () Обычно библиотеку с builtin'ами линкеру (lld) передает драйвер компилятора, будь то clang.exe или clang-cl.exe. Но в данном случае линкером заправляет MSBuild напрямую, который не знает, что нужно её использовать. Соответственно, драйвер никак не может передать флаги линкеру, поэтому приходится разбираться самим. if (CMAKE_GENERATOR MATCHES "Visual Studio")
link_libraries("$(LLVMInstallDir)\\lib\\clang\\\ ${CMAKE_CXX_COMPILER_VERSION}\\lib\\windows\\\ clang_rt.builtins-x86_64.lib") else() link_libraries(clang_rt.builtins-x86_64) endif() Ура! Сборка заработала. Однако дальше при запуске тестов нас ждала куча ошибок сегментации: Отладчик при этом показывает какое-то странное значение в IntegerInterval, а на самом деле проблема находится немного дальше: В разных структурах для Dataflow-механизма активно применяется ранее упомянутый тип Int128, а для работы с ним используются SIMD-инструкции. И падение вызвано невыровненным адресом: Инструкция MOVAPS перемещает из памяти набор чисел с плавающей запятой в регистры для SIMD-операций. Адрес при этом обязан быть выровнен, в его конце должен стоять 0, а оказалась 8. Придется помочь компилятору, задав правильное выравнивание: class alignas(16) Int128
Порядок.Последняя проблема вылезла из-за Docker-контейнеров: Сборка под MSVC всегда делалась со статической линковкой рантайма, а для экспериментов с Clang рантайм переключили на динамический. Оказалось, что в образах с Windows по умолчанию не установлены Microsoft Visual C++ Redistributable. Решили вернуть статическую линковку, чтобы у пользователей не возникало таких же неприятностей.ЗаключениеНесмотря на то, что пришлось немного повозиться с подготовкой проекта, мы остались довольны ростом производительности анализатора более чем на 10%.Последующие релизы PVS-Studio на Windows будут собираться с помощью компилятора Clang.Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Alexey Govorov, Sergey Larin. PVS-Studio Team: Switching to Clang Improved PVS-Studio C++ Analyzer's Performance. =========== Источник: habr.com =========== Похожие новости:
Блог компании PVS-Studio ), #_c++, #_sistemy_sborki ( Системы сборки ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:35
Часовой пояс: UTC + 5