Как стать автором
Поиск
Написать публикацию
Обновить
13.17

Компиляторы *

Из исходного кода в машинный

Сначала показывать
Порог рейтинга
Уровень сложности

О некоторых проблемах микрооптимизаций

Время на прочтение6 мин
Количество просмотров6.6K

Предыстория


Как-то раз у меня с коллегой завязался разговор по поводу улучшения инструментария для работы с битовыми флагами в перечислениях C++. На тот момент у нас уже была функция IsEnumFlagSet, принимающая на вход первым аргументом тестируемую переменную, вторым — набор флагов для проверки. Чем же она лучше старого доброго побитового И?

if (IsEnumFlagSet(state, flag)) 
{

}
// vs
if (state & flag) 
{

}
Читать дальше →

А суть-то в чём, или Минимизация исходников — проще, чем кажется

Время на прочтение9 мин
Количество просмотров6K

В эти чудесные январские дни всех нас, конечно, волнует вопрос минимизации исходного кода с сохранением инварианта. В смысле, не волнует?!? Зря… Вот упал у вас компилятор, а программа гигантская — как-то неудобно такое разработчикам слать. И тут начинается веселье: а если вот это выкинуть? О, не падает — ладно, оставляем, а если это? — всё ещё падает, и это, и это, и то… Ой, я компилятор на старых исходниках запускал.


В то же время, автоматизация поиска багов — дело-то житейское: git bisect, llvm-bugpoint, creduce,… В статье я опишу yet another способ решения проблемы упрощения тестового случая, более-менее универсальный по отношению к языку программирования, и покажу некоторые примеры использования.

Читать дальше →

ELFийские трюки в Go

Время на прочтение6 мин
Количество просмотров11K


В этой заметке мы научимся получать машинный код Go функции прямо в рантайме, распечатаем его с помощью дизассемблера и по пути узнаем несколько фокусов вроде получения адреса функции без её вызова.


Предупреждение: ничему полезному эта мини-статья вас не научит.

Читать дальше →

Как работает panic в Rust

Время на прочтение9 мин
Количество просмотров9.8K

Как работает паника в Rust


Что именно происходит, когда вы вызываете panic!()?
Недавно я потратил много времени на изучение частей стандартной библиотеки, связанных с этим и оказалось, что ответ довольно сложный!


Мне не удалось найти документы, объясняющие общую картину паники в Rust, так что это стоит записать.

Читать дальше →

ruleguard: динамические проверки для Go

Время на прочтение8 мин
Количество просмотров5.6K


В этой статье я расскажу о новой библиотеке (и утилите) статического анализа go-ruleguard, которая адаптирует gogrep для использования внутри линтеров.


Отличительная особенность: правила статического анализа вы описываете на особом Go-подобном DSL, который на старте ruleguard превращается в набор диагностик. Возможно, это один из самых легко конфигурируемых инструментов для реализации кастомных инспекций для Go.


В качестве бонуса, мы поговорим об go/analysis и его предшественниках.

Читать дальше →

О проблемах транслятора Python и переосмысление языка

Время на прочтение21 мин
Количество просмотров18K

Сколько нужно архитекторов, чтобы реализовать язык программирования?
Сто. Один будет писать реализацию, а 99 — говорить, что могут сделать лучше.


В этой статье я хочу затронуть не столько сам язык, сколько детали реализации CPython и его стандартной библиотеки, которые гарантируют, что у вас не будет никаких простых способов сделать приложение на питоне ни многопоточным, ни быстрым, ни легко поддерживаемым, и почему было создано столько альтернативных реализаций (PyPy, Cython, Jython, IronPython, Python for .NET, Parakeet, Nuitka, Stackless, Unladen Swallow), половина из которых уже умерла; и мало кто понял, почему у альтернатив не было шансов победить в борьбе за выживание против других языков. Да, есть GDScript, который призван решить проблемы с производительностью, есть Nim, который призван решить вообще все проблемы, не обязывая при этом пользователя чрезмерно явно объявлять типы. Однако, учитывая огромную инертность индустрии, я осознаю, что в ближайшие 10 лет новые языки точно не займут значимой ниши. Однако, я верю в то, что питон возможно сделать эффективным, изменив стиль написания кода, по большей части сохранив оригинальный синтаксис, и полностью сохраняя возможность взаимодействия кода нового и старого стиля. Я буду концентрироваться на проблемах CPython, а не ближайшего его конкурента, PyPy, поскольку PyPy на самом деле прыгает вокруг всё тех же проблем CPython.

Читать дальше →

Выпуск Rust 1.40.0: #[non_exhaustive], усовершенствования макросов и прочие улучшения

Время на прочтение5 мин
Количество просмотров5.6K

Команда Rust рада сообщить о выпуске новой версии, 1.40.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.


Если вы установили предыдущую версию Rust средствами rustup, то для обновления до версии 1.40.0 вам достаточно выполнить следующую команду:


$ rustup update stable

Если у вас ещё не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.


Что вошло в стабильную версию 1.40.0


Основными новшествами являются введение атрибута #[non_exhaustive], улучшения macros!() и #[attribute]. Наконец, миграционные предупреждения анализатора заимствований стали ошибками в Rust 2015. Смотрите подробности выпуска для дополнительной информации.

Читать дальше →

Как я 12 лет создавал свой ЯП и компилятор к нему

Время на прочтение22 мин
Количество просмотров50K


События истории рассказываются в хронологическом порядке, если вам кажется, что какое либо событие не относится к делу, то скорее всего — это не так, просто момент в котором будет понятно почему я упомянул это событие, будет позднее. Создаваемый мной язык, со временем менялся, если вы читаете и понимаете, что язык не очень и дальше можно не читать, то все же рекомендую дочитать до конца, возможно ваше мнение изменится. Изображение к статье не отражает главных особенностей языка, но в языке действительно нет ссылок.

Здравствуй, читатель! Меня зовут Александр, родился я в небольшом городке (меньше 10000 человек) в Беларуси. Моя семья была бедной, игрушек крайне мало, про компьютер и какие либо приставки вообще можно не заикаться. Не смотря на то, что семья была бедной, у матери были не бедные родственники, которые иногда дарили нам какие либо не дешевые вещи. И вот однажды (где то в 2001 году) эти самые родственники, дарят нам компьютер «Байт»(советский аналог ZX Spectrum 48k). Радости моей не было предела! Сразу же я начал, запускать на нем игры. Игры на этом компьютере загружались с обычных аудиокассет с магнитной лентой. Загрузка одной игры длилась примерно 5 минут и с не малой вероятностью, могла прекратиться из-за некачественного сигнала. Чтобы увеличить вероятность успешной загрузки, мне приходилось протирать спиртом и регулировать положение считывающей головки магнитофона. Весь этот шаманизм при загрузке, длительность загрузки и невозможность сохраняться в играх, привели к тому, что постепенно я начал терять интерес к играм. Но вместе с «Байт»-ом мне также подарили книгу, по работе с этим компьютером. Я решил прочитать эту книгу, чтобы узнать больше о возможностях «Байт»-а. В книге оказался учебник по встроенному в «Байт» языку программирования «Бэйсик».
Читать дальше →

Развитие компилятора C для нового мультиклета-нейропроцессора

Время на прочтение9 мин
Количество просмотров4.3K


На конференции разработчиков системного и инструментального ПО – OS DAY 2016, которая прошла в г. Иннополис 9-10 июня 2016 (Казань) при обсуждении доклада о мультиклеточной архитектуре была высказана мысль, что она будет наиболее эффективной при решении задач искусственного интеллекта. Условия для разработки нового процессора общего назначения, ориентированного на задачи ИИ, сложились в текущем году.

Нейропроцессор Мультиклет S2, проект которого был впервые представлен на Huawei Innovation Forum 2019 является дальнейшим развитием мультиклеточной архитектуры. От ранее созданных мультиклетов он отличается системой команд, а именно вводом новых типов малоразмерных данных (с фиксированной и плавающей запятой) и операций с ними. Увеличено количество клеток – 256 и частота – 2,5 ГГц, что должно обеспечить пиковую производительность 81,9 TФлопс на 16F и, соответственно, сделать его сравнимым, в части нейровычислений, с возможностями современных специализированных ASIC TPU (TPU-3: 90 Тфлопс на 16F).

Так как эффективность использования процессоров в значительной мере зависит от оптимальности компилятора разработана развиваемая схема оптимизации кода.
Рассмотрим ее более подробно.
Читать дальше →

Clang-format тормозит работу программы

Время на прочтение11 мин
Количество просмотров5.5K
Сегодня мы будем измерять производительность разных реализаций функции toupper, ведь именно этим и занимаются по вторникам.

Вообще-то мне нет никакого дела до функции toupper, просто я недавно писал другой пост и мне нужен был какой-то общий сюжетный стержень, а toupper кажется вполне интересным и безобидным кандидатом в бенчмарки. Я старался выбрать что-то максимально простое, что не увело бы меня в сторону, но так уж получилось, что в этом тесте я столкнулся со странной проблемой.
Читать дальше →

Паскаль играет в Go. Реализация методов и интерфейсов в любительском компиляторе

Время на прочтение3 мин
Количество просмотров3.8K
If I could export one feature of Go into other languages, it would be interfaces. — Russ Cox



Мой предельно простой компилятор Паскаля уже становился предметом двух публикаций на Хабре. Со времени их написания язык обзавёлся всеми недостающими средствами, положенными стандартному Паскалю, и многими плюшками, добавленными в Паскаль компанией Borland в её золотую пору. Компилятор также научился ряду простейших локальных оптимизаций, достаточных хотя бы для того, чтобы глаза не кровоточили при взгляде на листинг дизассемблера.

Тем не менее дебри объектно-ориентированного программирования остались совершенно нетронутыми. Так почему бы компилятору не послужить теперь полигоном для экспериментов в этой области? И почему бы нам не почерпнуть вдохновение из слов Расса Кокса, вынесенных в эпиграф? Попробуем реализовать в Паскале методы и интерфейсы в стиле Go. Затея интересна хотя бы тем, что все популярные в прошлом компиляторы Паскаля (Delphi, Free Pascal) по сути заимствовали объектную модель из C++. Любопытно посмотреть, как на той же почве приживётся совсем иной подход, позаимствованный из Go. Если вы вслед за мной готовы запастись изрядной долей иронии, отбросить вопрос «Зачем?» и воспринять происходящее как игру, добро пожаловать под кат.
Читать дальше →

Универсальный DSL. Возможно ли это?

Время на прочтение25 мин
Количество просмотров8.4K

Язык предметной области. Не перегружен конструкциями языка общего назначения. При этом позволяет всего несколькими строчками реализовать весьма сложную логику. Все это — DSL.

Однако создание DSL требует от разработчика соответствующей квалификации. Регулярное использование этого подхода превращается в рутину разработки очередного языка. Решением может стать создание универсального инструмента — движка, который будет применим к совершенно разным задачам и прост в модификации. В этой статье мы на C# разработаем простейший с точки зрения реализации, но при этом достаточно мощный языковой движок, при помощи которого можно решить достаточно широкий круг задач.
Читать дальше →

Проверка кода компилятора Ark Compiler, недавно открытого компанией Huawei

Время на прочтение6 мин
Количество просмотров11K
Picture 1

Во время презентаций летом 2019 года Huawei анонсировала технологию Ark Compiler. По заверениям представителей компании, этот проект с открытым исходным кодом позволяет существенно повысить плавность и отзывчивость Android и сторонних приложений. Новый интересный открытый проект по традиции должен пройти проверку качества кода с помощью PVS-Studio.

Введение


Впервые компилятор Huawei Ark был представлен вместе с запуском смартфонов Huawei P30 и P30 Pro. По заявлению Huawei, компилятор Ark повышает плавность работы Android на 24%, а скорость отклика – на 44%. При этом сторонние приложения для Android, после перекомпиляции с помощью Ark, могут работать на 60% быстрее. Открытый проект имеет название OpenArkCompiler. Его исходный код доступен на китайском аналоге сайта GitHub – Gitee.
Читать дальше →

Ближайшие события

Процесс компиляции программ на C++

Время на прочтение5 мин
Количество просмотров238K

Цель данной статьи:


В данной статье я хочу рассказать о том, как происходит компиляция программ, написанных на языке C++, и описать каждый этап компиляции. Я не преследую цель рассказать обо всем подробно в деталях, а только дать общее видение. Также данная статья — это необходимое введение перед следующей статьей про статические и динамические библиотеки, так как процесс компиляции крайне важен для понимания перед дальнейшим повествованием о библиотеках.

Читать дальше →

Как работает оптимизирующий компилятор

Время на прочтение23 мин
Количество просмотров19K

Оптимизирующие компиляторы — основа современного ПО: они позволяют программистам писать код на понятном для них языке, затем преобразуя его в код, который сможет эффективно исполняться оборудованием. Задача оптимизирующих компиляторов заключается в том, чтобы понять, что делает написанная вами входная программа, и создать выходную программу, которая делает всё то же самое, только быстрее.

В этой статье мы рассмотрим некоторые из основных методик приведения (inference techniques) в оптимизирующих компиляторах: как спроектировать программу, с которой компилятору будет легко работать; какие приведения можно сделать в вашей программе и как использовать их для её уменьшения и ускорения.
Читать дальше →

Что такое таблица виртуальных таблиц?

Время на прочтение7 мин
Количество просмотров15K
Однажды в Slack я наткнулся на новый акроним для моего глоссария акронимов C++: “VTT.” Godbolt:

test.o: In function `MyClass':
test.cc:3: undefined reference to `VTT for MyClass'

“VTT” в данном контексте означает «таблица виртуальных таблиц» (virtual table table). Это вспомогательная структура данных, используемая (в Itanium C++ ABI) при создании некоторых базовых классов, которые сами унаследованы от виртуальных базовых классов. VTT следуют тем же правилам размещения, что и виртуальные таблицы (vtable) и информация о типе (typeinfo), так что если вы получили ошибку, приведённую выше, вы можете просто мысленно подставить «vtable» вместо «VTT», и начать отладку. (Скорее всего, вы оставили неопределённой ключевую функцию класса). Для того, чтобы увидеть, почему VTT, или аналогичная структура, необходима, начнём с основ.
Читать дальше →

Реализация интерпретатора MSH

Время на прочтение3 мин
Количество просмотров2.1K
Реализация интерпретатора MSH. Хочу представить уважаемой публике интерпретатор нового языка программирования MSH. Я уже о нем писал статьи на Habr. Последняя из них Интерпретатор MSH. В этой статье есть ссылки на предыдущие статьи по этой тематике.
Читать дальше →

Как LLVM оптимизирует функцию

Время на прочтение10 мин
Количество просмотров10K
Оптимизирующий AOT-компилятор обычно структурирован так:

  1. фронтенд, преобразующий исходный код в промежуточное представление
  2. конвейер машинно-независимой оптимизации (IR): последовательность проходов, которые переписывают IR для устранения неэффективных участков и структур, которые не могут быть непосредственно преобразованы в машинный код. Иногда эту часть называют middle-end.
  3. Машинно-зависимый бэкенд для генерации ассемблерного кода или машинного кода.



В некоторых компиляторах формат IR остаётся неизменным на протяжении всего процесса оптимизации, в других его формат или семантика меняется. В LLVM формат и семантика фиксированы, и, следовательно, возможно запускать проходы в любой последовательности без риска неверной компиляции или аварийного завершения работы компилятора.
Читать дальше →

Инкремент элементов вектора

Время на прочтение13 мин
Количество просмотров17K
В каком случае инкремент элементов вектора std::vector будет быстрее – если они имеют тип uint8_t или uint32_t?

Чтобы не рассуждать отвлечённо, рассмотрим две конкретные реализации:

void vector8_inc(std::vector<uint8_t>& v)
{
  for (size_t i = 0; i < v.size(); i++)
  {
    v[i]++;
  }
}

void vector32_inc(std::vector<uint32_t>& v)
{
  for (size_t i = 0; i < v.size(); i++)
  {
    v[i]++;
  }
}
Попробуем угадать

Выпуск Rust 1.39.0: async/await, аттрибуты для параметров функций, новые константные функции

Время на прочтение4 мин
Количество просмотров9.6K

Команда Rust рада сообщить о выпуске новой версии, 1.39.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.


Если вы установили предыдущую версию Rust средствами rustup, то для обновления до версии 1.39.0 вам достаточно выполнить следующую команду:


$ rustup update stable

Если у вас ещё не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.


Что вошло в стабильную версию 1.39.0


Наиболее существенные нововведения включают в себя синтаксис async/.await, разделяемые ссылки к перемещаемым значениям в match-guards и атрибуты у параметров функций. Смотрите подробные примечания к выпуску для дополнительной информации.

Читать дальше →

Вклад авторов