Как улучшить сервис, не поменяв ни одной строки исходного кода
Литвинов Михаил
@litvinovmitch11
2/61
- Быстрое погружение в тему (или не очень...)
2/61
- Быстрое погружение в тему (или не очень...)
- Постараемся ответить на важный вопрос:
"Сырая ли это технология?"
2/61
3/61
- Порядок трансформаций
3/61
- Порядок трансформаций
- Векторизация инструкций
3/61
- Порядок трансформаций
- Векторизация инструкций
- Аллокация регистров
3/61
- Порядок трансформаций
- Векторизация инструкций
- Аллокация регистров
- Встраивание функций
3/61
CompilerGym - Facebook Research
ML-LLVM - IITH Research
MLGO - Google Research
4/61
CompilerGym - Facebook Research
- Phase Ordering Problem
ML-LLVM - IITH Research
MLGO - Google Research
4/61
CompilerGym - Facebook Research
- Phase Ordering Problem
- Phase Ordering, AutoVectorization, RegAlloc
ML-LLVM - IITH Research
MLGO - Google Research
4/61
CompilerGym - Facebook Research
- Phase Ordering Problem
- Phase Ordering, AutoVectorization, RegAlloc
ML-LLVM - IITH Research
MLGO - Google Research
- RegAlloc, Inlinig
4/61
5/61
- Сколько страдать, чтобы заработало
5/61
- Сколько страдать, чтобы заработало
- Сколько страдать, чтобы завершилось
5/61
- Сколько страдать, чтобы заработало
- Сколько страдать, чтобы завершилось
- Сколько страдать, чтобы понять, что все (не) зря
5/61
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
// Initialize targets for clang module support.
llvm::InitializeAllTargets();
auto ExpectedParser =
CommonOptionsParser::create(argc, argv, ClangCheckCategory);
if (!ExpectedParser) {
llvm::errs() << ExpectedParser.takeError();
return 1;
}
...
}
ELF Header:
Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0xe143f0
Start of program headers: 64 (bytes into file)
...
6/61
ELF Header:
Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0xe143f0
Start of program headers: 64 (bytes into file)
...
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
// Initialize targets for clang module support.
llvm::InitializeAllTargets();
auto ExpectedParser =
CommonOptionsParser::create(argc, argv, ClangCheckCategory);
if (!ExpectedParser) {
llvm::errs() << ExpectedParser.takeError();
return 1;
}
...
}
6/61
ELF Header:
Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0xe143f0
Start of program headers: 64 (bytes into file)
...
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
// Initialize targets for clang module support.
llvm::InitializeAllTargets();
auto ExpectedParser =
CommonOptionsParser::create(argc, argv, ClangCheckCategory);
if (!ExpectedParser) {
llvm::errs() << ExpectedParser.takeError();
return 1;
}
...
}
6/61
С, C++, Rust, ...
LLVM IR
Program analysis
Transform & optimize
CodeGen
ARM, X86, ...
7/61
С++
LLVM IR
INFO
OPT
CodeGen
ARM, X86
Pipelines (O1-O3, Os, Oz)
8/61
С++
LLVM IR
INFO
OPT
CodeGen
ARM, X86
Pipelines (O1-O3, Os, Oz)
8/61
С++
LLVM IR
INFO
OPT
CodeGen
ARM, X86
Pipelines (O1-O3, Os, Oz)
8/61
Простейший вид CFG
Control Flow Graph
Граф потока управления
9/61
Простейший вид CFG
Control Flow Graph
Граф потока управления
Заметим, что в NODE №3 никак не попасть
9/61
Простейший вид CFG
Control Flow Graph
Граф потока управления
Заметим, что в NODE №3 никак не попасть - ее можно не генерировать.
9/61
Простейший вид CFG
Control Flow Graph
Граф потока управления
- Упростили граф
- Уменьшили codesize
- Уменьшили время компиляции
9/61
Простейший вид CFG
Control Flow Graph
Граф потока управления
- Упростили граф
- Уменьшили codesize
- Уменьшили время компиляции
9/61
x = 10 y = 40
z = y - 30 y = 20
q = input() q *= z - x
Простейший вид CFG
Control Flow Graph
Граф потока управления
Рассмотрим тот же граф. Но добавим в вершины осмысленные выражения.
z = 10
10/61
x = 10 y = 40
z = y - 30
y = 20
Простейший вид CFG
Control Flow Graph
Граф потока управления
Добавим аннотации к каждой переменной в каждой вершине.
x = 10, y = 40
z, q = undef.
q = input() q *= z - x
z = 10
10/61
x = 10 y = 40
z = y - 30
y = 20
Простейший вид CFG
Control Flow Graph
Граф потока управления
x = 10, y = 40
z, q = undef.
x, z = 10 y = 20 q = undef.
q = input() q *= z - x
Добавим аннотации к каждой переменной в каждой вершине.
z = 10
10/61
x = 10 y = 40
z = y - 30
y = 20
Простейший вид CFG
Control Flow Graph
Граф потока управления
x = 10, y = 40
z, q = undef.
x, z = 10 y = 20 q = undef.
q = input() q *= z - x
Добавим аннотации к каждой переменной в каждой вершине.
z = 10
x, z = 10
y = 40 q = undef.
10/61
x = 10 y = 40
z = y - 30
y = 20
Простейший вид CFG
Control Flow Graph
Граф потока управления
x = 10, y = 40
z, q = undef.
x, z = 10 y = 20 q = undef.
q = input()
q *= z - x
Добавим аннотации к каждой переменной в каждой вершине.
z = 10
x, z = 10
y = 40 q = undef.
10/61
x = 10 y = 40
z = y - 30
y = 20
Простейший вид CFG
Control Flow Graph
Граф потока управления
x = 10, y = 40
z, q = undef.
x, z = 10
y, q = undef.
q = input()
q *= z - x
Добавим аннотации к каждой переменной в каждой вершине.
x, z = 10 y = 20 q = undef.
z = 10
x, z = 10
y = 40 q = undef.
10/61
x = 10 y = 40
z = y - 30
y = 20
q = input()
Простейший вид CFG
Control Flow Graph
Граф потока управления
x = 10, y = 40
z, q = undef.
q *= z - x
x, z = 10
y = undef.
z - x = 0
q = 0
Добавим аннотации к каждой переменной в каждой вершине.
x, z = 10 y = 20 q = undef.
x, z = 10
y, q = undef.
z = 10
x, z = 10
y = 40 q = undef.
10/61
x = 10 y = 40
q = input()
Простейший вид CFG
Control Flow Graph
Граф потока управления
q = 0
- Упростили выражения
- Получили выигрыш в рантайме
z = 10
z = 10
y = 20
10/61
x = 10 y = 40
q = input()
Простейший вид CFG
Control Flow Graph
Граф потока управления
q = 0
- Упростили выражения
- Получили выигрыш в рантайме
z = 10
z = 10
y = 20
10/61
11/61
11/61
11/61
11/61
Ура, удалось связать ML и компиляторы...
11/61
В компиляторе большое число (>100) независимых трансформаций.
От порядка выполнения трансформаций зависит результат.
PASS 1
PASS 2
PASS 3
PASS 4
PASS 1
PASS 2
PASS 3
PASS 4
PASS 1
PASS 2
PASS 3
PASS 4
PASS 1
PASS 2
PASS 3
PASS 4
12/61
Выбор наилучшей последовательности - NP полная задача.
Существуют дефолтные пайплайны, написанные экспертами, но они хороши лишь В СРЕДНЕМ.
На помощь приходит RL!
PASS 1
PASS 2
PASS 3
PASS 4
PASS 1
PASS 2
PASS 3
PASS 4
PASS 1
PASS 2
PASS 3
PASS 4
PASS 1
PASS 2
PASS 3
PASS 4
13/61
14/61
14/61
14/61
14/61
14/61
Продолжаем,
пока не устроит ревард
14/61
Векторные вычисления — такие вычисления, когда при выполнении одной инструкции процессора производится одновременно несколько однотипных операций.
15/61
vector<uint32_t> v1(n), v2(n), out(n);
for (size_t i = 0; i < n; ++i) {
out[i] = v1[i] + v2[i];
}
LLVM обнаружит, что цикл независим, данные выровнены, и тип данных подходит для векторизации. Цикл будет векторизован.
uint32_t a, b, c, d, e, f;
a = b + c;
d = e + f;
LLVM обнаружит, что операции независимы и имеют одинаковую структуру. Операции будут объединены в одну векторную операцию.
16/61
Поиск мест, подходящих для векторизации - задача, использующая различные эвристики.
Для этого поиска можно использовать ML.
Также существует возможность переорганизации кода таким образом, чтобы векторизация стала возможна (тоже ML).
17/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
- У виртуальных регистров есть время жизни
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
- В моменты использования виртуальных регистров - им должны соответствовать физические
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
- В моменты использования виртуальных регистров - им должны соответствовать физические
- Количество физических регистров ограничено
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
y
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
- В моменты использования виртуальных регистров - им должны соответствовать физические
- Количество физических регистров ограничено
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
y
x
x
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
- В моменты использования виртуальных регистров - им должны соответствовать физические
- Количество физических регистров ограничено
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
y
x
z
x
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
- В моменты использования виртуальных регистров - им должны соответствовать физические
- Количество физических регистров ограничено
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
y
x
z
x
t
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
- В моменты использования виртуальных регистров - им должны соответствовать физические
- Количество физических регистров ограничено
18/61
x = y + 1
z = x + y
t = 10 * z
q = t * y
o = z + y
b = y + t
....
....
y
x
z
x
t
q
- У виртуальных регистров есть время жизни
- Количество виртуальных регистров не ограничено
- В моменты использования виртуальных регистров - им должны соответствовать физические
- Количество физических регистров ограничено
18/61
19/61
19/61
for (size_t i = 0; i < n; ++i) {
f(i, v);
}
Инлайнинг - встраивание тела функции, вместо ее вызова
uint32_t f(size_t idx, vector<int> &v) {
v[idx] = 42;
}
20/61
for (size_t i = 0; i < n; ++i) {
f(i, v);
}
Инлайнинг - встраивание тела функции, вместо ее вызова
uint32_t f(size_t idx, vector<int> &v) {
v[idx] = 42;
}
20/61
for (size_t i = 0; i < n; ++i) {
f(i, v);
}
Инлайнинг - встраивание тела функции, вместо ее вызова
uint32_t f(size_t idx, vector<int> &v) {
v[idx] = 42;
}
for (size_t i = 0; i < n; ++i) {
v[i] = 42;
}
20/61
for (size_t i = 0; i < n; ++i) {
f(i, v);
}
Инлайнинг - встраивание тела функции, вместо ее вызова
uint32_t f(size_t idx, vector<int> &v) {
v[idx] = 42;
}
for (size_t i = 0; i < n; ++i) {
v[i] = 42;
}
20/61
Сейчас решение о необходимости встраивать функции компилятор принимает на основе различных эвристик (бюджет инлайнинга и др.)
Ручные формулы можно заменить на ML алгоритм, который выдедет наилучшую формулу инлайнинга в конкретном коде, а также сможет сам выделять признаки.
21/61
Окружение для циклических алгоритмов обучения с подкреплением
GYM
22/61
Environment
Задача оптимизации и модель компилятора
Action Space
Текущее состояние среды, пространство действий
Reward
Метрика оптимизации
Observation
Текущее представление окружения
23/61
GCC
LLVM
MLIR
loop_tool
Основное окружение - LLVM
Похожее окружение - GCC
Цикловые оптимизации - loop
Перемножение матриц - MLIR
24/61
Дискретно. Состоит из 123 трансформаций
(llvm opt --passes)
-add-discriminators
|
Add DWARF path discriminators
|
-adce
|
Aggressive Dead Code Elimination
|
-aggressive-instcombine
|
Combine pattern based expressions
|
-alignment-from-assumptions
|
Alignment from assumptions
|
-always-inline
|
Inliner for always_inline functions
|
-argpromotion
|
Promote ‘by reference’ arguments to scalars
|
-attributor
|
Deduce and propagate attributes
|
|
|
and more...
opt --passes
Пространство действий
25/61
AUTOPHASE
INST2VEC
PROGRAML
ETC.
INST2VEC
26/61
Состоит из 56 чисел, которые описывают различные статистики LLVM-IR
0 |
BBNumArgsHi |
Number of BB where total args for phi nodes is gt 5 |
1 |
BBNumArgsLo |
Number of BB where total args for phi nodes is [1, 5] |
2 |
onePred |
Number of basic blocks with 1 predecessor |
3 |
onePredOneSuc |
Number of basic blocks with 1 predecessor and 1 successor |
4 |
onePredTwoSuc |
Number of basic blocks with 1 predecessor and 2 successors |
5 |
oneSuccessor |
Number of basic blocks with 1 successor |
6 |
twoPred |
Number of basic blocks with 2 predecessors |
И так далее
27/61
Состоит из 200 чисел, полученных специальной кодировкой исходного кода
Предобработка кода
Кодирование текста
Получение эмбедингов
28/61
Основанное на графах представление LLVM-IR, которое включает в себя поток управления, поток данных и поток вызовов.
Основанное на графах представление LLVM-IR, которое включает в себя поток управления, поток данных и поток вызовов.
29/61
Награда - разница стоимостей
Ее можно нормировать на начальное значение
Либо на разницу с бейзлайном (O1-O3, Oz)
30/61
Количество LLVM-IR инструкций в программе
Размер .TEXT секции
31/61
Количество LLVM-IR инструкций в программе
Размер .TEXT секции
Потому что
измерять
performance
дорого
31/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
32/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
32/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
clang++-10 \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
bazel run \
-c opt //compiler_gym/bin:random_search -- \
--env=llvm-ic-v0 \
--benchmark=file:///$PWD/bench.bc
32/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
Тут могла бы быть реклама вашего скрипта...
33/61
33/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
Тут могла бы быть реклама вашего скрипта...
Пишем код обучения модели на Python
Пишем обертку над компилятором, которая включит:
1) Преобразование исходников в LLVM IR (clang -emit-llvm)
2) Вызов модели (вызов встроенного opt)
3) Преобразование LLVM IR в байткод (clang )
33/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
Тут могла бы быть реклама вашего скрипта...
А еще поддержан
только LLVM-10
Пишем код обучения модели на Python
Пишем обертку над компилятором, которая включит:
1) Преобразование исходников в LLVM IR (clang -emit-llvm)
2) Вызов модели (вызов встроенного opt)
3) Преобразование LLVM IR в байткод (clang )
33/61
Эмбединги кода - IR2Vec
Метрика - не только codesize,
но и performance
34/61
Эмбединги кода - IR2Vec
Метрика - не только codesize,
но и performance
А еще алгоритм обучения
интегрирован в форк LLVM...
34/61
IR2Vec - это отдельный проект от IITH
Используется для генерации распределенных представлений исходного кода.
Он может выделять внутренние характеристики кода, как это делал Inst2Vec.
Предобучение и выделение начального словаря представлений
Получение исходного кода
Генерация эмбедингов
35/61
Распределение циклов (деление циклов) используется для переорганизации циклов с целью дальнейшей векторизации или локализации.
for (size_t i = 0; i < 2n; ++i) {
v[i] += 42;
}
36/61
Распределение циклов (деление циклов) используется для переорганизации циклов с целью дальнейшей векторизации или локализации.
for (size_t i = 0; i < n; ++i) {
v[i] += 42;
}
for (size_t i = n; i < 2n; ++i) {
v[i] += 42;
}
for (size_t i = 0; i < 2n; ++i) {
v[i] += 42;
}
36/61
Распределение циклов (деление циклов) используется для переорганизации циклов с целью дальнейшей векторизации или локализации.
for (size_t i = 0; i < n; ++i) {
v[i] += 42;
}
for (size_t i = n; i < 2n; ++i) {
v[i] += 42;
}
for (size_t i = 0; i < 2n; ++i) {
v[i] += 42;
}
36/61
Награда для модели рассчитывается с учётом стоимости инструкций и количества промахов кэша в цикле.
Генерируем граф зависимостей для каждого цикла в программе.
Модель учится прогнозировать порядок распределения цикла.
37/61
Используя раскраски графов и уже изученный IR2Vec для эмбедингов, с помощью RL агента решается задача аллокации регистров
38/61
39/61
К счастью, больше писать Python код не придется. У IITH есть свой форк LLVM - ML-LLVM
(LLVM-10)
Проект RL4ReAl интегрирован в clang
Проекты POSET-RL и Loop-Distribution интегрированы в opt
39/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
40/61
clang++ \
-emit-llvm -c -O0 -Xclang -disable-O0-optnone \
-Xclang -disable-llvm-passes \
bench.cpp
Собрать ML-LLVM, с ONNX-runtime, получить clang и opt
Имеется возможность обучать свои модели
В кейсе clang просто подменяем компилятор с дефолтным конфигом настроек модели
В кейсе opt пишем обертку - скрипт, который сначала дергает clang -emit-llvm, затем opt, затем clang
40/61
Уже много раз обсуждалась задача аллокации регистров.
MLGO создали RegAlloc Advisor - специальный советник,
который предсказывает с помощью ML распределение регистров и помогает избрать лучшее распределение с целью увеличения perfomance.
41/61
Уже много раз обсуждалась задача аллокации регистров.
MLGO создали RegAlloc Advisor - специальный советник,
который предсказывает с помощью ML распределение регистров и помогает избрать лучшее распределение с целью увеличения perfomance.
Главное отличие от IITH - это интегрировано в основной LLVM-project!
41/61
Бюджет инлайнинга - число, определяющее какую сумму можно потратить на инлайнинг.
42/61
Бюджет инлайнинга - число, определяющее какую сумму можно потратить на инлайнинг.
Стоимость инлайнинга - число, для каждого вхождения функции, определяющее стоимость ее инлайнинга.
42/61
Бюджет инлайнинга - число, определяющее какую сумму можно потратить на инлайнинг.
Стоимость инлайнинга - число, для каждого вхождения функции, определяющее стоимость ее инлайнинга.
Расчет стоимости инлайнинга зависит от некотрых эвристик.
MLGO призван обучить ML модель, чтобы не изобретать формулы стоимостей инлайнинга.
42/61
43/61
Оба проекта интегрированы в дефолтный LLVM!
Нужно лишь запустить clang с правильными флагами
Дефолтные решения
clang++ -Oz -mllvm -enable-ml-inliner=default bench.cpp
clang++ -mllvm -regalloc-enable-advisor=default bench.cpp
43/61
44/61
Имеется возможность обучать свои модели
Собрать ml-compiler-opt, с tflite, обучить модели
Собрать LLVM,с флагами -DTENSORFLOW_AOT_PATH, -DLLVM_INLINER_MODEL_PATH
44/61
Имеется возможность обучать свои модели
Собрать ml-compiler-opt, с tflite, обучить модели
Есть классное demo на Github MLGO!
44/61
Собрать LLVM,с флагами -DTENSORFLOW_AOT_PATH, -DLLVM_INLINER_MODEL_PATH
45/61
Никаких проблем, просто в CMake указываем дополнительные флаги компилятору (если с моделями, то компилятору, собранному с флагами TF)!
-DCMAKE_CXX_FLAGS_RELEASE="-Oz -mllvm -enable-ml-inliner=release"
-DCMAKE_CXX_FLAGS_RELEASE="-mllvm -regalloc-enable-advisor=default"
45/61
Легко измерить и понять насколько хорош алгоритм или нет
Очень дорого собирать данные для обучения и замерять профит
46/61
InstCount
47/61
InstCount - проще, обычно уже имеем
47/61
CodeSize
InstCount - проще, обычно уже имеем
47/61
CodeSize - сложнее, нужен лишний пайплайн для сборки
InstCount - проще, обычно уже имеем
47/61
Создание окружения
48/61
Создание окружения - очень дорого
48/61
Создание окружения - очень дорого
LLVM-MCA
48/61
LLVM-MCA - моделирует пропускную способность конвейера инструкций
Создание окружения - очень дорого
48/61
Алгорим | Время | Codesize (geomean) |
---|---|---|
PPO + Guided Search | 69.821s | 1.070× |
Random search (t=10800) | 10,512.356s | 1.062× |
llvm-ic-v0
environment
cbench-v1
dataset
49/61
50/61
51/61
52/61
Утверждается, что получался прирост от 0.3% до 1.5% запросов в секунду
53/61
clang 3%
SPEC2006: до 6% (в среднем 1.75%)
Внутри Google: до 7%
54/61
Время компиляции при 4 потоках: ~ 1 час
Размер директории ./bin: 3.560 G
clang - 190.6 Mb
55/61
Время компиляции при 16 потоках: ~ 1 день
Размер директории ./bin: 3.7772 G
clang - 203.16 Mb
56/61
Время компиляции при 16 потоках: ~ 1 день
Размер директории ./bin: 3.7772 G
clang - 203.16 Mb
Фокус не удался(
CompilerGym необходимо настраивать, из коробки не работает
56/61
Время компиляции при 16 потоках: ~ 1 день, но на больших файлах - fallback
Размер директории ./bin: 3.536 G
clang - 186.06 Mb
57/61
Фокус удался!
Из коробки получили прирост в codesize для O3 ~ 1.004
57/61
Время компиляции при 16 потоках: ~ 1 день, но на больших файлах - fallback
Размер директории ./bin: 3.536 G
clang - 186.06 Mb
Время компиляции при 16 потоках: ~ 1.5 дня, так еще и приходилось рестартовать (где-то память, где-то ошибки)
Размер директории ./bin: 3.579 G
clang - 188.8 Mb
58/61
Фокус под вопросом?
Оверхед на размер не большой
58/61
Время компиляции при 16 потоках: ~ 1.5 дня, так еще и приходилось рестартовать (где-то память, где-то ошибки)
Размер директории ./bin: 3.579 G
clang - 188.8 Mb
Время компиляции при 4 потоках: ~ 1 час
Размер директории ./bin: 4.381 G
clang - 219.65 Mb
59/61
Время компиляции при 4 потоках: ~ 1 час
Размер директории ./bin: 3.832 G
clang - 196.45 Mb
60/61
Время компиляции при 4 потоках: ~ 1 час
Размер директории ./bin: 3.832 G
60/61
Фокус удался!
Из коробки получили прирост в codesize для Oz ~ 1.143
Время компиляции при 4 потоках: ~ 1 час
Размер директории ./bin: 3.832 G
clang - 196.45 Mb
61/61
Творческий вопрос, на который каждый сам ответит)
Но если не чуть-чуть приложить усилия и обучить модели - вполне!
61/61
Литвинов Михаил
@litvinovmitch11
CompilerGym - https://compilergym.com
AutoPhase - https://arxiv.org/pdf/2003.00671
Inst2Vec - https://arxiv.org/pdf/1806.07336
ProGraML - https://arxiv.org/pdf/2003.10536
CompilerGym GitHub - https://github.com/facebookresearch/CompilerGym
IITH - POSET-RL - https://compilers.cse.iith.ac.in/projects/posetrl
IITH - IR2VEC - https://compilers.cse.iith.ac.in/projects/ir2vec
IITH - LoopDist - https://compilers.cse.iith.ac.in/publications/rl_loop_distribution
IITH - RL4ReAl - https://compilers.cse.iith.ac.in/publications/rl4real
IITH - ML-LLVM - https://github.com/IITH-Compilers/ml-llvm-project
62/61