УСКОРЯЕМ СБОРКУ C++ ПРОЕКТОВ.
ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
ЛАПИЦКИЙ АРТЁМ
LAPITSKY.ARTEM@GMAIL.COM
1
Почему C++ проекты собираются так долго?
Какие есть способы ускорения сборки C++ кода
Что такое Unity сборки и как они работают
Практика использования Unity сборок
COREHARD // НАЧАЛО / СОДЕРЖАНИЕ
LAPITSKY ARTEM // COREHARD // 2017.10.14
О ЧЁМ БУДЕМ ГОВОРИТЬ
ПОЧЕМУ C++ ПРОЕКТЫ
СОБИРАЮТСЯ ТАК ДОЛГО?
3
Bjarne Stroustrup “The C++ Programming Language. Special
Edition”, 2017
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
ЧЕМ ЗАНИМАЕТСЯ КОМПИЛЯТОР ПРИ СБОРКЕ КОДА
#include <iostream>
int main()
{
std::cout << "Hello, World!n";
}
hello.cpp
4
Результат препроцессинга G++
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
ЧЕМ ЗАНИМАЕТСЯ КОМПИЛЯТОР ПРИ СБОРКЕ КОДА (2)
$ gcc hello.cpp -E > hello.gcc.preprocessed.cpp
$ stat -x hello.gcc.preprocessed.cpp
File: "hello.gcc.preprocessed.cpp"
Size: 1233499 FileType: Regular File
$ cloc hello.gcc.preprocessed.cpp
1 text file.
1 unique file.
0 files ignored.
github.com/AlDanial/cloc v 1.74 T=0.25 s (4.0 files/s, 152999.5 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C++ 1 6824 0 30995
-------------------------------------------------------------------------------
5
Результат препроцессинга MSVC++
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
ЧЕМ ЗАНИМАЕТСЯ КОМПИЛЯТОР ПРИ СБОРКЕ КОДА (3)
> cl /E hello.cpp > hello.vc.preprocessed.cpp
> cloc hello.vc.preprocessed.cpp
1 text file.
1 unique file.
0 files ignored.
github.com/AlDanial/cloc v 1.74 T=0.26 s (3.8 files/s, 192740.0 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C++ 1 23331 0 27286
-------------------------------------------------------------------------------
6
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
C++ И МОДУЛИ
7
Каждый этап трансляции полностью зависит от результата
предыдущих
Трансляция unit’а не может быть распараллелена
Требуется минимум 3 прохода по исходному коду
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
ОСОБЕННОСТИ ПРОЦЕССА ТРАНСЛЯЦИИ C++ КОДА
8
#include делает текстовую подстановку содержимого
заголовочного файла
Смысл подставленного текста полностью зависит от всего, что
было в исходном файле до этого
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
МОДУЛЬНОСТЬ ЧЕРЕЗ ЗАГОЛОВОЧНЫЕ ФАЙЛЫ
#include <foo.h>
...
#define true (bool(__LINE__ % 2))
#include <foo.h>
9
Невозможно использовать повторно результат обработки
заголовочного файла (даже в рамках одного translation unit)
Лишние #include директивы создают массу бессмысленной
работы для компилятора
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
МОДУЛЬНОСТЬ ЧЕРЕЗ ЗАГОЛОВОЧНЫЕ ФАЙЛЫ (2)
10
Выполнение метапрограмм может занимать значительную
часть времени трансляции
Инстанцирование шаблонов происходит в каждом translation
unit отдельно (используйте extern template)
COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО?
LAPITSKY ARTEM // COREHARD // 2017.10.14
TEMPLATE METAPROGRAMMING
СПОСОБЫ УСКОРЕНИЯ СБОРКИ
12
Специальный тип заголовочного файла
Исключена зависимость от контекста включения
Повторное включение заголовочных файлов, включённых в PCH
не должно влиять на смысл программы
Требуется одинаковый набор параметров компилятора для всех
единиц трансляции, которые используют PCH
Их можно компилировать!
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
PRECOMPILED HEADERS (PCH)
13
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
PRECOMPILED HEADERS (PCH)
cpp2
cpp1
header1 header2 headern
…
TU1
TU2
14
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
PRECOMPILED HEADERS (PCH)
cpp2
cpp1
header1 header2 headern
…
TU1
TU2
PCH
15
Ограничения и особенности
Каждый translation unit может использовать ровно один PСH
Нужно быть внимательным к различиям директив препроцессора
разных translation unit
Требует внесения изменений в структуру и параметры сборки
проекта
Нюансы реализации в разных компиляторах
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
PRECOMPILED HEADERS (PСH)
16
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
КЭШИРОВАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ
source code
flags and options
compiler digest
output
compiler
object file
cache
caching service
compiler
17
Для каждого набора входных данных компилятора
сохраняется результат его работы
Схема очень эффективна, когда большая часть
транслируемого кода не меняется
Вторая и последующие сборки до 10-ти раз быстрее первой
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
КЭШИРОВАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ (2)
18
Особенности и ограничения:
Первоначальная сборка всегда дольше сборки без кэширования
Необходимость повторной сборки при изменении даже
незначительных параметров компиляции
Иногда кэшируются «битые» объектные файлы
Плохо работает с механизмом PCH
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
КЭШИРОВАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ (3)
19
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
РАСПРЕДЕЛЁННАЯ СБОРКА
CoordinatorWorkstation
Agent1
build
compile
a1.cpp…an.cpp Agent2
Agent3
compile
c1.cpp…cn.cpp
compile
b1.cpp…bn.cpp
compile
d1.cpp…dn.cpp
20
Особенности и ограничения:
Эффективность сильно зависит от конкретной реализации и
конфигурации сети
Некорректная работа какого-либо из агентов не позволяет успешно
собрать проект
Отладка проблем сборки становится сложнее
COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ
LAPITSKY ARTEM // COREHARD // 2017.10.14
РАСПРЕДЕЛЁННАЯ СБОРКА (2)
UNITY BUILD
22
Идея: максимально уменьшить количество компилируемых
исходных файлов
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD
23
Объединим все исходные .cpp файлы в один: Unity pack
Исключён повторный разбор и анализ одних и тех же
заголовочных файлов
Не инстанцируются по многу раз одни и те же шаблоны
Сильно упрощается процесс линковки
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD (2)
The Dalai Lama walks into a pizza shop and says
"can you make me one with everything?"
24
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD (3)
45
42
10
7
12
6
0
10
20
30
40
50
60
Visual Studio 2017 Xcode 8.3
Время сборки одного проекта, мин.
Nothing Unity Build IncrediBuild Unity Build + IncrediBuild
25
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD: BEFORE
src1.cpphdr1.h
Headers
hdr2.h hdr3.h
Sources
src2.cpp src3.cpp
Your project
26
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD: AFTER
src1.cpphdr1.h
Headers
hdr2.h hdr3.h
Sources
src2.cpp src3.cpp
Your project unity project
unity_pack.cpp
#include "src1.cpp"
#include "src2.cpp"
#include "src3.cpp"
unity_pack.cpp
27
Использование только одного Unity Pack’а неэффективно
Современные CPU имеют более одного ядра и несколько Unity
pack’ов могут собираться параллельно
Слишком большой Unity pack может вызвать ошибку “out of
memory” или привести к неэффективности процесса компиляции
Множество исходных файлов следует рассредоточить по
нескольким Unity pack’ам
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD: USE EFFECTIVELY
28
Генерацию Unity pack’ов стоит автоматизировать
Рабочее решение на CMake
https://github.com/dava/dava.engine/blob/development/Sources/
CMake/Modules/UnityBuild.cmake
Reducing Compilation Time: Unity Builds © Christoph Heindl
https://cheind.wordpress.com/2009/12/10/reducing-compilation-
time-unity-builds/
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD: AUTOMATE IT!
29
COREHARD // UNITY BUILD
LAPITSKY ARTEM // COREHARD // 2017.10.14
UNITY BUILD: AUTOMATE IT! (2)
Пример проекта на CMake
...
set (HEADER_FILES hdr1.h hdr2.h hdr3.h)
set (SOURCE_FILES src1.cpp src2.cpp src3.cpp)
if (UNITY_BUILD)
# generate unity pack files and add them to ${SOURCE_FILES}
generate_unity_packs(MyProject SOURCE_FILES)
endif()
add_executable(MyProject ${HEADER_FILES} ${SOURCE_FILES})
CMakeLists.txt
ПРАКТИКА ИСПОЛЬЗОВАНИЯ
UNITY-СБОРОК
31
Необходимы модификации исходного кода
Не использовать глобальные static переменные
Не использовать анонимные namespace
Ограничить использование директивы using namespace
Для всех #define необходимы соответствующие #undef
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
АДАПТАЦИЯ ПРОЕКТА К UNITY-СБОРКЕ
32
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
STATIC И АНОНИМНЫЕ NAMESPACE
...
static int my_local_var = 0;
namespace {
void my_local_function() {
std::cout << “src1n";
}
}
int src1_process() {
my_local_var = 1;
my_local_function();
}
src1.cpp
...
static int my_local_var = 0;
namespace {
void my_local_function() {
std::cout << “src2n";
}
}
int src2_process() {
my_local_var = 2;
my_local_function();
}
src2.cpp
unity_pack.cpp
33
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
STATIC И АНОНИМНЫЕ NAMESPACE (2)
...
namespace Ssrc1 {
int my_local_var = 0;
void my_local_function() {
std::cout << “src1n";
}
}
int src1_process() {
using namespace Ssrc1;
my_local_var = 1;
my_local_function();
}
src1.cpp
...
namespace Ssrc2 {
int my_local_var = 0;
void my_local_function() {
std::cout << “src2n";
}
}
int src2_process() {
using namespace Ssrc2;
my_local_var = 2;
my_local_function();
}
src2.cpp
unity_pack.cpp
34
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
USING NAMESPACE
...
#include <vector>
using namespace std;
int foo() {
vector<int> numbers;
}
int bar() {
vector<string> strings;
}
src.cpp
...
#include <vector>
int foo() {
using namespace std;
vector<int> numbers;
}
int bar() {
using namespace std;
vector<string> strings;
}
src.cpp
35
Некоторые исходные файлы придётся вынести из unity
pack’ов
если используются специфические системные API
если в проекте есть конфликтующие внешние зависимости
Процесс адаптации можно автоматизировать
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
АДАПТАЦИЯ ПРОЕКТА К UNITY-СБОРКЕ (2)
36
Благодаря небольшому и предсказуемому времени сборки
кажется хорошей идеей, но
это ведёт к беспорядку с include’ами
не все IDE справляются с разбором и анализом unity pack’ов
изменение в исходном файле (.cpp) — это пересборка одного
unity_pack’а
изменение в заголовочном файле (.h) — это пересборка 1..N
unity_pack’ов
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
РАЗРАБОТКА В UNITY-ПРОЕКТЕ
37
Указанные проблемы решаются использованием механизма
избирательного исключения из Unity сборки тех частей
проекта, в которых будет вестись активная разработка
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
РАЗРАБОТКА В UNITY-ПРОЕКТЕ. ПОЛУ-UNITY
...
set (PERSONAL_IGNORES "Dir1/" "Dir2/" "Dir3/")
UnityIgnoreList.cmake
38
За
Огромный прирост скорости компиляции и компоновки
Одинаково высокая скорость как первой, так и последующих
сборок
При адаптации кода вырезается copy-paste
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
SUMMARY
39
Против
Требует модификации исходного кода
Накладывает ограничение на использование возможностей C++
Требуется большой объём оперативной памяти при сборке
COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК
LAPITSKY ARTEM // COREHARD // 2017.10.14
SUMMARY (2)
СПАСИБО ЗА ВНИМАНИЕ!
ЛАПИЦКИЙ АРТЁМ
Software Developer https://www.facebook.com/WargamingMinsk
ANY QUESTIONS?
lapitsky.artem@gmail.com
wargaming.com
https://www.linkedin.com/company/wargaming-net

Ускоряем сборку С++ проектов. Практика использования unity-сборок

  • 1.
    УСКОРЯЕМ СБОРКУ C++ПРОЕКТОВ. ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК ЛАПИЦКИЙ АРТЁМ LAPITSKY.ARTEM@GMAIL.COM
  • 2.
    1 Почему C++ проектысобираются так долго? Какие есть способы ускорения сборки C++ кода Что такое Unity сборки и как они работают Практика использования Unity сборок COREHARD // НАЧАЛО / СОДЕРЖАНИЕ LAPITSKY ARTEM // COREHARD // 2017.10.14 О ЧЁМ БУДЕМ ГОВОРИТЬ
  • 3.
  • 4.
    3 Bjarne Stroustrup “TheC++ Programming Language. Special Edition”, 2017 COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 ЧЕМ ЗАНИМАЕТСЯ КОМПИЛЯТОР ПРИ СБОРКЕ КОДА #include <iostream> int main() { std::cout << "Hello, World!n"; } hello.cpp
  • 5.
    4 Результат препроцессинга G++ COREHARD// ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 ЧЕМ ЗАНИМАЕТСЯ КОМПИЛЯТОР ПРИ СБОРКЕ КОДА (2) $ gcc hello.cpp -E > hello.gcc.preprocessed.cpp $ stat -x hello.gcc.preprocessed.cpp File: "hello.gcc.preprocessed.cpp" Size: 1233499 FileType: Regular File $ cloc hello.gcc.preprocessed.cpp 1 text file. 1 unique file. 0 files ignored. github.com/AlDanial/cloc v 1.74 T=0.25 s (4.0 files/s, 152999.5 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- C++ 1 6824 0 30995 -------------------------------------------------------------------------------
  • 6.
    5 Результат препроцессинга MSVC++ COREHARD// ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 ЧЕМ ЗАНИМАЕТСЯ КОМПИЛЯТОР ПРИ СБОРКЕ КОДА (3) > cl /E hello.cpp > hello.vc.preprocessed.cpp > cloc hello.vc.preprocessed.cpp 1 text file. 1 unique file. 0 files ignored. github.com/AlDanial/cloc v 1.74 T=0.26 s (3.8 files/s, 192740.0 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- C++ 1 23331 0 27286 -------------------------------------------------------------------------------
  • 7.
    6 COREHARD // ПОЧЕМУC++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 C++ И МОДУЛИ
  • 8.
    7 Каждый этап трансляцииполностью зависит от результата предыдущих Трансляция unit’а не может быть распараллелена Требуется минимум 3 прохода по исходному коду COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 ОСОБЕННОСТИ ПРОЦЕССА ТРАНСЛЯЦИИ C++ КОДА
  • 9.
    8 #include делает текстовуюподстановку содержимого заголовочного файла Смысл подставленного текста полностью зависит от всего, что было в исходном файле до этого COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 МОДУЛЬНОСТЬ ЧЕРЕЗ ЗАГОЛОВОЧНЫЕ ФАЙЛЫ #include <foo.h> ... #define true (bool(__LINE__ % 2)) #include <foo.h>
  • 10.
    9 Невозможно использовать повторнорезультат обработки заголовочного файла (даже в рамках одного translation unit) Лишние #include директивы создают массу бессмысленной работы для компилятора COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 МОДУЛЬНОСТЬ ЧЕРЕЗ ЗАГОЛОВОЧНЫЕ ФАЙЛЫ (2)
  • 11.
    10 Выполнение метапрограмм можетзанимать значительную часть времени трансляции Инстанцирование шаблонов происходит в каждом translation unit отдельно (используйте extern template) COREHARD // ПОЧЕМУ C++ ПРОЕКТЫ СОБИРАЮТСЯ ТАК ДОЛГО? LAPITSKY ARTEM // COREHARD // 2017.10.14 TEMPLATE METAPROGRAMMING
  • 12.
  • 13.
    12 Специальный тип заголовочногофайла Исключена зависимость от контекста включения Повторное включение заголовочных файлов, включённых в PCH не должно влиять на смысл программы Требуется одинаковый набор параметров компилятора для всех единиц трансляции, которые используют PCH Их можно компилировать! COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 PRECOMPILED HEADERS (PCH)
  • 14.
    13 COREHARD // СПОСОБЫУСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 PRECOMPILED HEADERS (PCH) cpp2 cpp1 header1 header2 headern … TU1 TU2
  • 15.
    14 COREHARD // СПОСОБЫУСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 PRECOMPILED HEADERS (PCH) cpp2 cpp1 header1 header2 headern … TU1 TU2 PCH
  • 16.
    15 Ограничения и особенности Каждыйtranslation unit может использовать ровно один PСH Нужно быть внимательным к различиям директив препроцессора разных translation unit Требует внесения изменений в структуру и параметры сборки проекта Нюансы реализации в разных компиляторах COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 PRECOMPILED HEADERS (PСH)
  • 17.
    16 COREHARD // СПОСОБЫУСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 КЭШИРОВАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ source code flags and options compiler digest output compiler object file cache caching service compiler
  • 18.
    17 Для каждого наборавходных данных компилятора сохраняется результат его работы Схема очень эффективна, когда большая часть транслируемого кода не меняется Вторая и последующие сборки до 10-ти раз быстрее первой COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 КЭШИРОВАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ (2)
  • 19.
    18 Особенности и ограничения: Первоначальнаясборка всегда дольше сборки без кэширования Необходимость повторной сборки при изменении даже незначительных параметров компиляции Иногда кэшируются «битые» объектные файлы Плохо работает с механизмом PCH COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 КЭШИРОВАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ (3)
  • 20.
    19 COREHARD // СПОСОБЫУСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 РАСПРЕДЕЛЁННАЯ СБОРКА CoordinatorWorkstation Agent1 build compile a1.cpp…an.cpp Agent2 Agent3 compile c1.cpp…cn.cpp compile b1.cpp…bn.cpp compile d1.cpp…dn.cpp
  • 21.
    20 Особенности и ограничения: Эффективностьсильно зависит от конкретной реализации и конфигурации сети Некорректная работа какого-либо из агентов не позволяет успешно собрать проект Отладка проблем сборки становится сложнее COREHARD // СПОСОБЫ УСКОРЕНИЯ СБОРКИ LAPITSKY ARTEM // COREHARD // 2017.10.14 РАСПРЕДЕЛЁННАЯ СБОРКА (2)
  • 22.
  • 23.
    22 Идея: максимально уменьшитьколичество компилируемых исходных файлов COREHARD // UNITY BUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD
  • 24.
    23 Объединим все исходные.cpp файлы в один: Unity pack Исключён повторный разбор и анализ одних и тех же заголовочных файлов Не инстанцируются по многу раз одни и те же шаблоны Сильно упрощается процесс линковки COREHARD // UNITY BUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD (2) The Dalai Lama walks into a pizza shop and says "can you make me one with everything?"
  • 25.
    24 COREHARD // UNITYBUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD (3) 45 42 10 7 12 6 0 10 20 30 40 50 60 Visual Studio 2017 Xcode 8.3 Время сборки одного проекта, мин. Nothing Unity Build IncrediBuild Unity Build + IncrediBuild
  • 26.
    25 COREHARD // UNITYBUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD: BEFORE src1.cpphdr1.h Headers hdr2.h hdr3.h Sources src2.cpp src3.cpp Your project
  • 27.
    26 COREHARD // UNITYBUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD: AFTER src1.cpphdr1.h Headers hdr2.h hdr3.h Sources src2.cpp src3.cpp Your project unity project unity_pack.cpp #include "src1.cpp" #include "src2.cpp" #include "src3.cpp" unity_pack.cpp
  • 28.
    27 Использование только одногоUnity Pack’а неэффективно Современные CPU имеют более одного ядра и несколько Unity pack’ов могут собираться параллельно Слишком большой Unity pack может вызвать ошибку “out of memory” или привести к неэффективности процесса компиляции Множество исходных файлов следует рассредоточить по нескольким Unity pack’ам COREHARD // UNITY BUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD: USE EFFECTIVELY
  • 29.
    28 Генерацию Unity pack’овстоит автоматизировать Рабочее решение на CMake https://github.com/dava/dava.engine/blob/development/Sources/ CMake/Modules/UnityBuild.cmake Reducing Compilation Time: Unity Builds © Christoph Heindl https://cheind.wordpress.com/2009/12/10/reducing-compilation- time-unity-builds/ COREHARD // UNITY BUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD: AUTOMATE IT!
  • 30.
    29 COREHARD // UNITYBUILD LAPITSKY ARTEM // COREHARD // 2017.10.14 UNITY BUILD: AUTOMATE IT! (2) Пример проекта на CMake ... set (HEADER_FILES hdr1.h hdr2.h hdr3.h) set (SOURCE_FILES src1.cpp src2.cpp src3.cpp) if (UNITY_BUILD) # generate unity pack files and add them to ${SOURCE_FILES} generate_unity_packs(MyProject SOURCE_FILES) endif() add_executable(MyProject ${HEADER_FILES} ${SOURCE_FILES}) CMakeLists.txt
  • 31.
  • 32.
    31 Необходимы модификации исходногокода Не использовать глобальные static переменные Не использовать анонимные namespace Ограничить использование директивы using namespace Для всех #define необходимы соответствующие #undef COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 АДАПТАЦИЯ ПРОЕКТА К UNITY-СБОРКЕ
  • 33.
    32 COREHARD // ПРАКТИКАИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 STATIC И АНОНИМНЫЕ NAMESPACE ... static int my_local_var = 0; namespace { void my_local_function() { std::cout << “src1n"; } } int src1_process() { my_local_var = 1; my_local_function(); } src1.cpp ... static int my_local_var = 0; namespace { void my_local_function() { std::cout << “src2n"; } } int src2_process() { my_local_var = 2; my_local_function(); } src2.cpp unity_pack.cpp
  • 34.
    33 COREHARD // ПРАКТИКАИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 STATIC И АНОНИМНЫЕ NAMESPACE (2) ... namespace Ssrc1 { int my_local_var = 0; void my_local_function() { std::cout << “src1n"; } } int src1_process() { using namespace Ssrc1; my_local_var = 1; my_local_function(); } src1.cpp ... namespace Ssrc2 { int my_local_var = 0; void my_local_function() { std::cout << “src2n"; } } int src2_process() { using namespace Ssrc2; my_local_var = 2; my_local_function(); } src2.cpp unity_pack.cpp
  • 35.
    34 COREHARD // ПРАКТИКАИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 USING NAMESPACE ... #include <vector> using namespace std; int foo() { vector<int> numbers; } int bar() { vector<string> strings; } src.cpp ... #include <vector> int foo() { using namespace std; vector<int> numbers; } int bar() { using namespace std; vector<string> strings; } src.cpp
  • 36.
    35 Некоторые исходные файлыпридётся вынести из unity pack’ов если используются специфические системные API если в проекте есть конфликтующие внешние зависимости Процесс адаптации можно автоматизировать COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 АДАПТАЦИЯ ПРОЕКТА К UNITY-СБОРКЕ (2)
  • 37.
    36 Благодаря небольшому ипредсказуемому времени сборки кажется хорошей идеей, но это ведёт к беспорядку с include’ами не все IDE справляются с разбором и анализом unity pack’ов изменение в исходном файле (.cpp) — это пересборка одного unity_pack’а изменение в заголовочном файле (.h) — это пересборка 1..N unity_pack’ов COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 РАЗРАБОТКА В UNITY-ПРОЕКТЕ
  • 38.
    37 Указанные проблемы решаютсяиспользованием механизма избирательного исключения из Unity сборки тех частей проекта, в которых будет вестись активная разработка COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 РАЗРАБОТКА В UNITY-ПРОЕКТЕ. ПОЛУ-UNITY ... set (PERSONAL_IGNORES "Dir1/" "Dir2/" "Dir3/") UnityIgnoreList.cmake
  • 39.
    38 За Огромный прирост скоростикомпиляции и компоновки Одинаково высокая скорость как первой, так и последующих сборок При адаптации кода вырезается copy-paste COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 SUMMARY
  • 40.
    39 Против Требует модификации исходногокода Накладывает ограничение на использование возможностей C++ Требуется большой объём оперативной памяти при сборке COREHARD // ПРАКТИКА ИСПОЛЬЗОВАНИЯ UNITY-СБОРОК LAPITSKY ARTEM // COREHARD // 2017.10.14 SUMMARY (2)
  • 41.
  • 42.
    ЛАПИЦКИЙ АРТЁМ Software Developerhttps://www.facebook.com/WargamingMinsk ANY QUESTIONS? lapitsky.artem@gmail.com wargaming.com https://www.linkedin.com/company/wargaming-net