Обновить
50

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

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

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

История портирования Reindexer'а – как покорить Эльбрус за 11 дней

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

Всем привет! На связи Антон Баширов, разработчик из ИТ-кластера «Ростелекома». Импортозамещение набирает обороты, а российский софт всё глубже проникает в нашу повседневную ИТ-шную сущность бытия. Процессоры Эльбрус и Байкал становятся более востребованными, комьюнити расширяется, но мысли о необходимости портировать весь наш любимый технологический стек на неизведанную архитектуру E2K звучат страшнее рассказов про горящий в пламени production-кластер.

Работая в команде по внедрению Эльбрусов, мне довелось в прямом и переносном смысле пощупать наши отечественные процессоры, поэтому я хочу поделиться полученным опытом, рассказать о том, какой болевой порог нужен, чтобы выдержать портирование NoSql native базы данных и не сойти с ума, а еще познакомить разработчиков с миром Эльбруса и его обитателями.

Читать далее

Сборка ядра Linux с LTO оптимизацией

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


Технический прогресс не стоит на месте, появляются новые компьютерные архитектуры, компиляторы становятся умнее и генерируют более быстрый машинный код. Современные задачи требуют все более креативного и эффективного решения. В данной статье пойдет речь, на мой взгляд, про один из самых прогрессивных тулчейнов LLVM и компиляторы на его основе Clang и Clang++, для языков программирования С и C++ соответственно. Хоть GCC — конкурент Clang, может агрессивнее оптимизировать циклы и рекурсию, Clang дает на выходе более корректный машинный код, и чаще всего не ломает поведение приложений. Плюс оптимизация программ не заканчивается только оптимизацией циклов, поэтому Clang местами дает лучшую производительность. В GCC же за счет переоптимизации вероятность получить unpredictable behavior значительно выше. По этой причине на многих ресурсах не рекомендуют использовать -O3 и LTO(Link Time Optimization) оптимизации для сборки программ. Плюс в случае агрессивной оптимизации, размер исполняемых файлов может сильно увеличиться и программы на практике будут работать даже медленнее. Поэтому мы остановились на Clang не просто так и опции компиляции -O3 и LTO работают в нем более корректно. Плюс современные компиляторы более зрелые, и сейчас уже нет тех детских болячек переоптимизации и LTO.
Узнать подробности

Sparkplug — неоптимизирующий компилятор JavaScript в подробностях

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

Создать компилятор JS с высокой производительностью означает сделать больше, чем разработать сильно оптимизированный компилятор, например TurboFan, особенно это касается коротких сессий, к примеру, загрузки сайта или инструментов командной строки, когда большая часть работы выполняется до того, как оптимизирующий компилятор получит хотя бы шанс на оптимизацию, не говоря уже о том, чтобы располагать временем на оптимизацию. Как решить эту проблему? К старту курса о Frontend-разработке делимся переводом статьи о Sparkplug — свече зажигания под капотом Chrome 91.

Читать далее

C++20: удивить линкер четырьмя строчками кода

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

Представьте себе, что вы студент, изучающий современные фичи C++. И вам дали задачу по теме concepts/constraints. У преподавателя, конечно, есть референсное решение "как правильно", но для вас оно неочевидно, и вы навертели гору довольно запутанного кода, который всё равно не работает. (И вы дописываете и дописываете всё новые перегрузки и специализации шаблонов, покрывая всё новые и новые претензии компилятора).

А теперь представьте себе, что вы — преподаватель, который увидел эту гору, и захотел помочь студенту. Вы стали упрощать и упрощать его код, и даже тупо комментировать куски юнит-тестов, чтобы оно хоть как-то заработало... А оно всё равно не работает. Причём, в зависимости от порядка юнит-тестов, выдаёт разные результаты или вообще не собирается. Где-то спряталось неопределённое поведение. Но какое?

Сперва преподаватель (то есть, я) минимизировал код вот до такого: https://gcc.godbolt.org/z/TaMTWqc1T

Читать далее

С++23 WIP: онлайн-встреча международного комитета по C++

Время на прочтение4 мин
Количество просмотров15K
Вчера прошла встреча рабочей группы ISO C++, добавляли фичи в C++23, исправляли C++20. Мы участвуем в работе комитета, поэтому сегодня поделюсь с вами свежими новостями о развитии стандарта.



Должен заметить, что международный комитет в онлайне работает совсем уж неторопливо… Настолько неторопливо, что на февральской встрече из полезного приняли только std::to_underlying() — функцию, преобразовывающую значение enum к нижележащему целочисленному типу:

enum class ABCD : std::uint64_t { A = 0x1012, B = 0x405324, };

constexpr std::uint64_t value = std::to_underlying(ABCD::A); 

В этот раз дело пошло веселее

Разработка стековой виртуальной машины и компилятора под неё (часть II)

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

В первой части Разработка стековой виртуальной машины и компилятора под неё (часть I) сделал свою элементарную стековую виртуальную машину, которая умеет работать со стеком, делать арифметику с целыми числами со знаком, условные переходы и вызовы функций с возвратом. Но так как целью было создать не только виртуальную машину, но и компилятор C подобного языка, пришло время сделать первые шаги в сторону компиляции. Опыта никакого. Буду действовать по разумению.

Одним из первых этапов компиляции является лексический разбор исходного кода нашего "C подобного языка" (кстати, надо какое-то название дать как только он станет более формальным). Задача простая - "нарубить" массив символов (исходный код) на список классифицированных токенов, чтобы последующий синтаксический разбор и генерация кода не вызывали сложности.

Читать далее

Разработка стековой виртуальной машины и компилятора под неё (часть I)

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

Так сложилось, что за последние 18 лет, не приходилось писать на C/C++. На работе использовалась Java, да и ввиду должностей деятельность больше была связана с предпринимательством - переговоры, корпоративные продажи, выстраивание производственных операций и структурирование инвестиционных сделок. Захотелось в свободное от работы время восстановить навыки, размять часть мозга которую не напрягал все 18 лет и, естественно, начать с самых основ. Осталось придумать себе задачу.

В универе преподаватели, молодость которых приходилась на 70-80е годы, до объектно-ориентированного программирования убивались по теме разработке собственных языков (интерпретаторов, компиляторов) под предметные области. Всё это казалось мне невостребованным "старьём", но появление новых языков за последнее десятилетие (Go, Kotlin и множества других) повысили мой интерес к этой теме.

Решил в качестве хобби написать 32-bit стековую виртуальную машину и компилятор C подобного языка под неё, чтобы восстановить базовые навыки. Такая классическая Computer Science задачка для заполнения вечеров с пивом. Как предприниматель, я четко понимаю, что она никому не нужна, но такая практика нужна мне для эстетического инженерного удовольствия. Плюс когда об этом рассказываешь сам понимаешь глубже. С целью и мотивами определился. Начнём.

Так как это виртуальная машина, мне нужно определиться с её характеристиками:

CPU: 32-bitный набор команд, так как машина стековая, в основном операнды команд храним в стеке, из регистров только IP (Instruction Pointer) и SP (Stack Pointer), пока работаем с целыми числами со знаком (__int32), позже добавим остальные типы данных.

RAM: пусть памяти пока будет 65536 ячеек по 32-bit`а. Которую организуем просто. С нижних адресов в верх будут идти код (code/text) и данные (data, heap), а с верхних адресов вниз будет расти стек (stack). Дёшево и сердито.

Читать далее

Необычная концепция синтаксиса языка программирования

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


Хочу представить на обсуждение читателей немного необычный концепт языка программирования, в котором отсутствует проблема, присущая практически всем промышленным языкам — постоянное увеличение сложности синтаксиса языка из-за его естественного развития по мере выхода новых версий и добавления новых фич. Эта проблема описана в материале Простое сложное программирование и Какая «идеальная» цель развития у языков программирования?

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

Особенности языка:

  • Низкий порог входа и естественное ограничение уровня сложности в течение длительного времени даже при условии постоянного развития самого языка.
  • Возможность писать код программы как в декларативной, так и в императивной парадигме с использованием процедурного, модульного и объектно-ориентированного подхода.

Ну и в соответствии с собственным наблюдением Хабр — ума палата, буду рад любым комментариям и предложениям, которые помогут протестировать или улучшить предлагаемое решение.
Читать дальше →

M/o/Vfuscator2, безумный компилятор

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


Однажды один умный чувак (Кристофер Домас) читал статью другого умного чувака (Стивена Долана) про удивительную особенность архитектуры x86. Стивен ругал её за избыточность и утверждал, что набор инструкций можно сократить до одной лишь mov, потому что она Тюринг-полная. Если бы Стивен не был таким умным, в его словах можно было бы усомниться, но у Кристофера загорелись глаза: проработав двадцать лет с x86, он не слышал ни о чём подобном, и ему страшно захотелось написать компилятор, который бы переводил весь код в наборы одних лишь mov-инструкций. Так родились M/o/Vfuscator и M/o/Vfuscator2, наглядно иллюстрирующие ненормальное программирование.
Читать дальше →

Планирование редакции Rust 2021

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

Мы рады объявить третью редакцию языка Rust — Rust 2021, которая выйдет в октябре. Rust 2021 содержит несколько небольших изменений, которые, тем не менее, значительно улучшат удобство использования Rust.


Что такое Редакция?


Релиз Rust 1.0 установил "стабильность без застоя" как основное правило Rust. Начиная с релиза 1.0, это правило звучало так: выпустив функцию в стабильной версии, мы обязуемся поддерживать её во всех будущих выпусках.


Однако есть случаи, когда возможность вносить небольшие изменения в язык бывает полезной — даже если у них нет обратной совместимости. Самый очевидный пример — введение нового ключевого слова, которое делает недействительными переменные с тем же именем. Например, в первой версии Rust не было ключевых слов async и await. Внезапное изменение этих слов на ключевые слова в более поздних версиях привело бы к тому, что, например код let async = 1; перестал работать.


Редакции — механизм, который мы используем для решения этой проблемы. Когда мы хотим выпустить функцию без обратной совместимости, мы делаем её частью новой редакции Rust. Редакции опциональны и должны прописываться явно, поэтому существующие пакеты не видят эти изменения, пока явно не перейдут на новую версию. Это означает, что даже последняя версия Rust по-прежнему не будет рассматривать async как ключевое слово, если не будет выбрана версия 2018 или более поздняя. Этот выбор делается для каждого пакета как части Cargo.toml. Новые пакеты, созданные cargo new, всегда настроены на использование последней стабильной редакции.

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

Как LLVM оптимизирует суммы степеней

Время на прочтение5 мин
Количество просмотров5.3K
LLVM оптимизирует суммы степеней, например:

int sum(int count)
{
  int result = 0;

  for (int j = 0; j < count; ++j)
    result += j*j;

  return result;
}

генерируя код, вычисляющий результат без цикла (godbolt):

sum(int):
        test    edi, edi
        jle     .LBB0_1
        lea     eax, [rdi - 1]
        lea     ecx, [rdi - 2]
        imul    rcx, rax
        lea     eax, [rdi - 3]
        imul    rax, rcx
        shr     rax
        imul    eax, eax, 1431655766
        add     eax, edi
        shr     rcx
        lea     ecx, [rcx + 2*rcx]
        lea     eax, [rax + rcx]
        add     eax, -1
        ret
.LBB0_1:
        xor     eax, eax
        ret

Также обрабатываются более сложные случаи (godbolt) – то есть оптимизация здесь не просто сравнивает паттерны. В этом посте мы рассмотрим, как выполняется эта оптимизация.
Читать дальше →

Rust 1.52.0: улучшения Clippy и стабилизация API

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

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


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


rustup update stable

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


Что было стабилизировано в 1.52.0


Самое значительное изменение этого выпуска не касается самого языка или стандартной библиотеки. Это улучшения в Clippy.


Ранее запуск cargo clippy после cargo check не запускал Clippy: кэширование в Cargo не видело разницы между ними. В версии 1.52 это поведение было исправлено, а значит, теперь пользователи будут получать то поведение, которое ожидают, независимо от порядка запуска этих команд.

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

Чему равно выражение -3/3u*3 на С++? Не угадаете. Ответ: -4. Приглашаю на небольшое расследование

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

Не уверен, что это будет исправлено.

Небольшое расследование под катом.

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

Clarion — Язык программирования, про который все забыли. А мне пришлось вспомнить

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

В своем первом посте я хочу рассказать об одном из самых редких и старых языков программирования - Clarion. Я знаком со всей линейкой этих замечательных языков начиная с 2.1 далее 5.0, 6.0, 6.3, 8 и до 9.1 по текущий момент. Буду постепенно рассказывать общие детали данной технологии, мало кому может оказаться полезным, но крайне мало инфы об этой технологии в Рунете, поэтому хочу чтобы осталась память о данной технологии на просторах Сети.

Мое первое "соприкосновение" произошло примерно 13-14 лет (98-99), когда я, по воле случая, познакомился с программистом на работе у родителей. Это был бородатый дядька по имени Евгений Иванович. Меня сразу же завлекли его беседы про Базы данных, операторы, переменные, функции...

Читать далее

Начинаем писать под stm8, выбираем среды разработки и стартуем

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

На пути в программировании stm8 есть развилка, о ней сегодня и поговорим.

Определимся что речь будет идти о средах которые могут писать под си. Для начала поговорим о подходах, я выделю 2 основных.

Первый установка ST Visual Develop и выбор в качестве компилятора COSMIC Бывший платный, а ныне бесплатный, но со своими заморочками; регистрация, получение ключа, и прочие танцы с бубном.

Второй же вариант, более простой VS Code + PlatformIO и компилятор SDCC полностью свободный. И опять же не все так просто. Sdcc не умеет исключать не используемые функции. Я решил этот вопрос хоть и успешно, но не без дополнительных действий при написании кода.
Читать далее

Передача и вызов лямбд на сервере и отказаться от docker/deploy/…

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

При разработке клиент-серверного приложения, у меня всегда появляется вопрос, а как я его буду разворачивать на сервере, упаковать его в jar/war/docker после написания кода, а потом еще надо передать на сервер, и еще много сделать телодвижений чтоб просто засунуть кусок кода на сервере.

Было бы хорошо просто передать на сервер код, как лямбду, так же как мы передаем лямбду в функцию, так же на сервер ее передать.

Но у меня появилась мысль как сделать этот процесс проще, и у меня что-то получилось.

Читать далее

Какая «идеальная» цель развития у языков программирования?

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


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

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

Об этой проблеме меня заставила задуматься первоапрельская статья «Доказательное программирование»

Понятно, что дата публикации статьи говорит сама за себя. Тем не менее, новые стандарты С++, постоянно выходящие спецификации Java или новый синтаксис у PHP 8, невольно заставляют задуматься, а в нужную ли сторону идет развитие языков программирования? Ведь большинство нововведений добавляют сложность в основной рабочий инструмент и решая одни проблемы, неявно добавляя множество других.

А что должно быть в конце прогресса у развития такой дисциплины как программирование? Или хотя бы у одного конкретного языка? Ради достижения какой конечной «идеальной» цели разрабатываются новые стандарты языков программирования?
Читать дальше →

Мультиклеточная архитектура: тесты и развитие

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

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

«Мультиклеточный процессор — это что?»

«Мультиклет R1 — первые тесты»

«Компилятор С/С++ на базе LLVM для мультиклеточных процессоров: быть или не быть?»

«Перспектива: MultiClet S1»

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

Первое, что необходимо сказать, – Мультиклет концептуально переходит от разработки отдельных процессоров к разработке мультиклеточной платформы на основе MultiClet B – базового элемента, состоящего из 4 клеток.  

Читать далее

Rust 1.51.0: const generics MVP, новый распознаватель функциональности Cargo

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

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


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


rustup update stable

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


Что было стабилизировано в 1.51.0


Этот выпуск представляет одно из наиболее крупных дополнений языка Rust и Cargo за долгое время, включающее в себя стабилизацию константных обобщений в минимально полезном варианте и новый распознаватель функциональности в Cargo. Давайте посмотрим подробнее!

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

Один бинарник, любое окружение. Магия чистого C

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


Как мы представляем себе кроссплатформенность? Мы пишем программу на языке, который либо компилируется в исполняемый файл отдельно для каждой поддерживаемой платформы, либо использует разновидность виртуальной машины вместо бинарника (и тогда эта среда должна присутствовать в целевых системах). Есть также и низкоуровневые языки, на которых писать серьёзные программы менее удобно, чем на высокоуровневых монстрах со своими компиляторами или рантаймами, но зато такие программы менее требовательны к предустановленному софту или наличию ОС в принципе, как и менее разборчивы в архитектуре. И всё же, есть возможность писать один и тот же код и собирать один и тот же бинарь под все популярные архитектуры и ОС (и даже bare metal), и эта возможность появилась благодаря гениальной Justine Tunney. Она написала Cosmopolitan, библиотеку на C, позволяющую исполнять один и тот же код на любой машине, подобно Java… но без какого-либо предустановленного интерпретатора или виртуальной машины! Один и тот же скомпилированный файл может исполняться как минимум в любом дистрибутиве Linux, на Mac OS, Windows NT, FreeBSD, OpenBSD, и NetBSD и на bare-metal на x86 и ARM*. Это настоящая магия.

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