Alvaros
.
- Регистрация
- 14.05.16
- Сообщения
- 21.452
- Реакции
- 101
- Репутация
- 204
Месяц назад я
Я решил развить исследование de Vos, взяв в качестве «эталонного кода» компилятор LLVM/Clang. У него сразу несколько преимуществ перед содержимым /usr/bin неназванной версии неназванной ОС:
Начну со статистики по мартовскому релизу LLVM 10.0:
В прошлом топике комментаторы
А вот распределение по числу инструкций:
Неожиданно, что код для SPARC на 11% состоит из nop-ов, заполняющих
А как набор используемых инструкций менялся со временем?
Единственная ISA, для которой в каждом релизе есть официальный бинарник — это i386:
Серая линия, отложенная на правой оси — это число разных инструкций, использованных в компиляторе. Как мы видим, некоторое время назад компилятор компилировался гораздо разнообразнее. int3 стала использоваться для заполнения промежутков только с 2018; до этого использовались такие же nop, как и для выравнивания внутри функций. Здесь же видно, что выравнивание внутри функций стало использоваться с 2013; до этого nop-ов было гораздо меньше. Ещё интересно, что до 2016 mov-ы составляли почти половину компилятора.
Самые первые версии LLVM, до появления clang, выпускались ещё и с бинарниками для SPARC. Потом поддержка SPARC утратила актуальность, и вновь она появилась лишь через 14 лет — с на порядок увеличившимся числом nop-ов:
Исторически следующая ISA, для которой выпускались бинарники LLVM — это PowerPC: сначала для Mac OS X и затем, после десятилетнего перерыва, для RHEL. Как видно из графика, переход после этого перерыва к 64-битному варианту ISA сопровождался заменой большинства lwz на ld, и вдобавок удвоением разнообразия инструкций:
В бинарниках для x86_64 и ARM частота использования разных инструкций почти не изменялась:
При подсчёте инструкций ARM я отсекал
Наконец, самая недавняя ISA, для которой публикуются официальные бинарники — это AArch64. Здесь интересно то, что orr с прошлого года почти перестала использоваться:
PowerPC и AArch64 оказались единственными ISA, для которых число разных используемых инструкций всё растёт и растёт.
You must be registered for see links
, сколько разных инструкций поддерживается современными процессорами, и насчитал 945 в Ice Lake. Комментаторы
You must be registered for see links
: какая часть всего этого разнообразия реально используется компиляторами? Например, некто Pepijn de Vos в 2016
You must be registered for see links
, сколько разных инструкций задействовано в бинарниках у него в /usr/bin, и насчитал 411 — т.е. примерно треть всех инструкций x86_64, существовавших на тот момент, не использовались ни в одной из стандартных программ в его ОС. Другая любопытная его находка — что код для x86_64 на треть состоит из инструкций mov. (В общем-то
You must be registered for see links
, что одних инструкций mov достаточно, чтобы написать любую программу.)Я решил развить исследование de Vos, взяв в качестве «эталонного кода» компилятор LLVM/Clang. У него сразу несколько преимуществ перед содержимым /usr/bin неназванной версии неназванной ОС:
- С ним удобно работать: это один огромный бинарник, по размеру сопоставимый со всем содержимым /usr/bin среднестатистического линукса;
- Он позволяет сравнить разные ISA: на
You must be registered for see linksдоступны официальные бинарники для x86, ARM, SPARC, MIPS и PowerPC;
- Он позволяет отследить исторические тренды: официальные бинарники доступны для всех релизов начиная с 2003;
- Наконец, в исследовании компиляторов логично использовать компилятор и в качестве подопытного объекта
Начну со статистики по мартовскому релизу LLVM 10.0:
| ISA | Размер бинарника | Общее число инструкций | Число разных инструкций |
|---|---|---|---|
| AArch64 | 97 МБ | 13,814,975 | 195 |
| ARMv7A | 101 МБ | 15,621,010 | 308 |
| i386 | 106 МБ | 20,138,657 | 122 |
| PowerPC64LE | 108 МБ | 17,208,502 | 288 |
| SPARCv9 | 129 МБ | 19,993,362 | 122 |
| x86_64 | 107 МБ | 15,281,299 | 203 |
You must be registered for see links
, что самый компактный код у них получается для SPARC. Здесь же видим, что бинарник для AArch64 оказывается на треть меньше что по размеру, что по общему числу инструкций.А вот распределение по числу инструкций:
Неожиданно, что код для SPARC на 11% состоит из nop-ов, заполняющих
You must be registered for see links
. Для i386 среди самых частых инструкций видим и int3, заполняющую промежутки между функциями, и nop, используемую для выравнивания циклов на строки кэша. Наблюдение de Vos о том, что код на треть состоит из mov, подтверждается на обоих вариантах x86; но даже и на load-store-архитектурах mov оказывается если не самой частой инструкцией, то второй после load.А как набор используемых инструкций менялся со временем?
Единственная ISA, для которой в каждом релизе есть официальный бинарник — это i386:
Серая линия, отложенная на правой оси — это число разных инструкций, использованных в компиляторе. Как мы видим, некоторое время назад компилятор компилировался гораздо разнообразнее. int3 стала использоваться для заполнения промежутков только с 2018; до этого использовались такие же nop, как и для выравнивания внутри функций. Здесь же видно, что выравнивание внутри функций стало использоваться с 2013; до этого nop-ов было гораздо меньше. Ещё интересно, что до 2016 mov-ы составляли почти половину компилятора.
Самые первые версии LLVM, до появления clang, выпускались ещё и с бинарниками для SPARC. Потом поддержка SPARC утратила актуальность, и вновь она появилась лишь через 14 лет — с на порядок увеличившимся числом nop-ов:
Исторически следующая ISA, для которой выпускались бинарники LLVM — это PowerPC: сначала для Mac OS X и затем, после десятилетнего перерыва, для RHEL. Как видно из графика, переход после этого перерыва к 64-битному варианту ISA сопровождался заменой большинства lwz на ld, и вдобавок удвоением разнообразия инструкций:
В бинарниках для x86_64 и ARM частота использования разных инструкций почти не изменялась:
При подсчёте инструкций ARM я отсекал
You must be registered for see links
— вместе с ними получалось около тысячи разных инструкций, но даже и без них ARM сильно опережает другие ISA по разнообразию генерируемых инструкций. Таким образом, слой b на этом графике включает и все условные переходы тоже. Для остальных ISA, где условными могут быть только переходы и немногие другие инструкции, суффиксы условий при подсчёте не отсекались.Наконец, самая недавняя ISA, для которой публикуются официальные бинарники — это AArch64. Здесь интересно то, что orr с прошлого года почти перестала использоваться:
PowerPC и AArch64 оказались единственными ISA, для которых число разных используемых инструкций всё растёт и растёт.



