Обновить
99.13

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

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

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

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

Время на прочтение3 мин
Охват и читатели7.6K


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

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

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

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

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

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

Время на прочтение8 мин
Охват и читатели8.5K

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

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

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

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

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

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

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

Читать далее

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

Время на прочтение7 мин
Охват и читатели6.7K

Команда 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*. Это настоящая магия.

Ускоряем нейросеть на уровне железа: интервью с разработчиком компиляторов

Время на прочтение8 мин
Охват и читатели5.7K

Обыденное представление о Deep Learning состоит в том, что для достижения успеха нужно хорошо знать математику и уметь программировать на Python. Но все становится немного сложнее, как только мы начинаем говорить о реализации нейросетевых решений в железе, где критична производительность. Мы пообщались с руководителем направления российского Исследовательского центра Samsung Вячеславом Гарбузовым, чтобы понять, как ускоряют работу нейросетей на аппаратном уровне, при чем тут компиляторы и какие знания требуются в этой редкой профессии. И самое интересное - какие вакансии в его подразделении открыты в настоящий момент.

Читать далее

Wasp — DSL для разработки веб-приложений

Время на прочтение4 мин
Охват и читатели4.9K


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

Ahead-of-Time компиляция и Blazor

Время на прочтение3 мин
Охват и читатели5.6K

В .NET 6 запланирована поддержка AOT компиляции для Blazor WebAssembly приложений. Давайте попробуем запустить в Preview 2 версии.

Анонса и инструкций пока что нету. Поэтому и решено написать этот пост.

Читать далее

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

Время на прочтение3 мин
Охват и читатели6K

Рабочая группа Rust 2021 Edition рада сообщить, что следующая редакция Rust — Rust 2021 — запланирована на этот год. Пока что формально описывающий её RFC остаётся открытым, но мы ожидаем, что в скором времени он будет принят. Планирование и подготовка уже начались, и мы идём по графику!


Если вам интересно, какие новшества появятся в Rust 2021 или когда эта редакция выйдет в стабильной версии, — читайте нашу статью!


Что входит в эту редакцию?


Конечный список нововведений, которые войдут в Rust 2021, ещё не определён до конца. В целом мы планируем, что выпуск Rust 2021 будет намного меньше, чем Rust 2018, по следующим причинам:


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

Более подробно о развитии концепции редакций вы можете почитать в RFC.


Решение, войдёт ли та или иная функциональность в Rust 2021, является частью процесса RFC — поэтому список ожидаемых функций может и будет меняться. Это будет происходить до самого момента выпуска, но тем не менее, уже сейчас мы можем рассмотреть список функций, которые, скорее всего, в неё войдут.

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

Кросс-компилятор для Raspberry Pi4

Время на прочтение6 мин
Охват и читатели12K

Хочу рассказать, как я собрал себе кросс-компилятор для Raspberry Pi4 с помощью crosstool-ng. Возможно кому-то тема покажется слишком примитивной и скучной. Я и сам поначалу думал, что быстро смогу собрать кросс-компилятор, но пришлось повозиться и изучать вопрос, некоторые нюансы были для меня неожиданны. Дальше расскажу что и как я делал.
Читать дальше →

Как скомпилировать Python

Время на прочтение10 мин
Охват и читатели68K

Привет, Хабр!

Я хочу рассказать об удивительном событии, о котором я узнал пару месяцев назад. Оказывается, одна популярная python-утилита уже более года распространяется в виде бинарных файлов, которые компилируются прямо из python. И речь не про банальную упаковку каким-нибудь PyInstaller-ом, а про честную Ahead-of-time компиляцию целого python-пакета. Если вы удивлены так же как и я, добро пожаловать под кат.

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

Rust 1.50.0: улучшение индексации массивов, безопасность полей объединений и усовершенствование файловых дескрипторов

Время на прочтение4 мин
Охват и читатели5.6K

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


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


rustup update stable

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


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


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

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

Threadripper 3990X: компилируем 1 миллиард строк C++ на 64 ядрах

Время на прочтение16 мин
Охват и читатели16K


RAD Studio состоит из Delphi и C++Builder. Компилятор Object Pascal в Delphi является однопроходным компилятором, и сам компилятор не является параллельным, однако при компиляции нескольких проектов параллельно он оказался способен скомпилировать 1 миллиард строк кода Object Pascal за 5 минут на машине с 16-ядерным AMD Ryzen 9 5950x. Я хотел выяснить, возможно ли сделать что-то подобное для C++. Этот пост является частью серии статей, в которой мы исследуем значительный прирост производительности, которого можно достичь на самых быстрых на начало 2021 года процессорах. Сколько это — 1 миллиард строк кода? Взгляните сюда.

Cheney on the M.T.A.: компилятор, в котором стек служит заодно и кучей

Время на прочтение8 мин
Охват и читатели4.8K
 
Did he ever return? No, he never returned,
And his fate is still unlearned,
He may ride forever ‘neath the streets of Boston,
He’s the man who never returned.

“Charlie on the M.T.A.”, 1949

1. Замыкания


Одна из удобных возможностей современных языков программирования – вложенные функции:

def bubble(arr, comp):

    def swap(i, j):
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp

    flag = True
    while flag:
        flag = False
        for i in range(len(arr) - 1):
            if comp(arr[i], arr[i+1]) > 0:
                swap(i, i+1)
                flag = True

Сама эта возможность не нова: она была уже в Алголе (1958) и многим знакома из Паскаля (1970). В компиляции вложенных функций нет ничего сложного: например, в стековом кадре внутренней функции может храниться указатель на стековый кадр внешней функции, чтобы внутренняя функция могла обращаться к параметрам и локальным переменным внешней. Кто-то может вспомнить, что инструкции enter и leave, появившиеся в 80186 (1982), реализуют именно такую поддержку вложенных функций (хотя я не встречал ни один компилятор, который бы её задействовал).

Сложности начинаются, если язык позволяет передать внутреннюю функцию наружу внешней:

def by_field(name):

    def comp(x, y):
        return x[name] – y[name]

    return comp

bubble(my_records, by_field("year"))

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

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

Клонированные переменные

Время на прочтение5 мин
Охват и читатели2.5K

Как-то попалось интересное (для меня), хотя и довольно давнее обсуждение языков программирования, где упоминался и язык PL/1. В конце концов, как всегда и бывает на таких форумах, все стороны остались при своем мнении, и тогда один из участников предложил написать на разных языках и затем сравнить простой тест, один из тех, которые часто дают студентам «для закрепления пройденного»:

 Стандартный входной поток содержит произвольное (и заранее не известное) количество целых чисел. Нужно все их прочитать, а затем вывести нечетные числа в стандартный выходной поток в порядке, обратном исходному. Чтобы "не заслонять лес деревьями", будем считать, что доступная память бесконечна. Критерии сравнения предлагаю следующие (в порядке убывания их приоритета):

Читать далее

Погружаемся в логово ржавчины. Как работает компилятор rust

Время на прочтение16 мин
Охват и читатели20K

В моей предыдущей статье о rust я попытался рассказать об истории языка, и показать откуда он пришёл. В статье было сделано множество упрощений. Просто нереальное множество. Народу не понравилось. Но в опросе, в конце статьи вы сказали, что надо бы показать кишки компилятора.

Ну что же, под катом вы найдёте разбор исходных кодов компилятора rust. Мы проследим путь программы, начиная из исходного файла, прямиком к бинарнику.

Ну, Fe2+mH2O + 2OH- = mH2O + Fe(OH)2↓

Тактическая оптимизация или результаты одного тестирования

Время на прочтение5 мин
Охват и читатели2K

Как-то в одном ЖЖ возникло обсуждение работы транслятора IBM для Windows с языка PL/1. Для алгоритмически довольно простого решения стационарного уравнения теплопроводности методом Либмана ответ вообще не удавалось получить, поскольку быстро возникало исключение типа «исчезновение порядка» («антипереполнение»). Мне предложили попробовать решить задачу своим транслятором, изначально разработанным для x86.

Поясню саму эту несложную задачу: матрица T (в примере 5000х5000) значений float первоначально заполняется вся нулями и единицами «по краям» - верхняя строка и левый столбец. Затем начинается длительный итерационный процесс изменения этой матрицы (N=5000)

Читать далее

Экстракоды при синтезе программ

Время на прочтение12 мин
Охват и читатели2.3K

Впервые термин «экстракод» я услышал еще применительно к командам БЭСМ-6. Сейчас это слово практически не используется, наиболее близкое понятие - «системный вызов». Из-за особенностей системы команд БЭСМ-6, те экстракоды действительно больше напоминали дополнительные встроенные инструкции, чем, например, вызов функции в MS-DOS с помощью INT 21H.

Смысл термина «экстракод» вполне прозрачен: это расширение системы команд для того, чтобы создать из реальной машины виртуальную машину для заданного языка, например, Паскаль-машину или Лисп-машину. А транслятор после этапа анализа исходного текста программы должен провести синтез программы – т.е. перевести результаты анализа в команды этой виртуальной машины.

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

Читать далее

Ограничение прав доступа к переменным

Время на прочтение4 мин
Охват и читатели5.3K

Конец восьмидесятых. Всего два года я отсутствовал на родном предприятии, а меня встретил уже меняющийся компьютерный мир. В отделах стали появляться персоналки: у кого IBM-PC/XT, у кого «Правец», а у кого ЕС-1840. Число пользователей БЭСМ-6 и даже ЕС и СМ-4 стало асимптотически приближаться к нулю. На фоне новых возможностей все их «фишки» сразу побледнели. Например, смешно, что еще недавно какая-нибудь замена терминала VT-340 на VT-52100 c памятью на 5 страниц, позволяющей вводить текст еще до включения БЭСМ, казалась важной.

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

Впрочем, последние годы работа с БЭСМ-6 через диалоговую программу «Пульт» разработки МГУ, как раз очень напоминала работу за первыми персоналками и поэтому переход был несложным.

А вот задачи стали другие. Отдел занимался разработкой ПО системы управления «Энергия-Буран». Точнее, отдел занимался комплексацией, верификацией, взаимодействием с наземным ПО и т.п., а собственно разработкой занималось сразу несколько отделов. Я впервые принимал участие в проекте, где были заняты десятки программистов. Язык программирования – ПРОЛ-2 разработки ИПМ АН СССР.

Вообще-то, девичья фамилия этого языка была «Пролог-Ц» от ПРОграммирования ЛОГики. А литера «Ц» - это, вероятно, ЦУП. Но поскольку в то время на слуху был японский Пролог с его транспьютерами, вероятно разработчикам надоело отвечать на вопросы о применении транспьютеров в «Буране», поэтому вторая версия языка вышла под таким скромным и безликим именем.

Язык был специфический, для задач управления. Типичный алгоритм выглядел так: выдать такую-то команду, подождать 0.3 миллисекунды, проверить такую-то переменную. Если она нулевая – выдать другую команду и запустить такой-то процесс. И все в таком духе.

Разумеется, инструментальных средств под x86 еще не было. Поэтому в отделе родилась идея, а затем – предложение – указание – распоряжение – создать отладочный или, точнее, проверочный транслятор для персоналки. Во-первых, он облегчит процесс комплексирования и верификации, а во-вторых, возможно, несколько увеличит производительность и в других отделах, сократив число подходов к штатному транслятору (на ЕС ЭВМ).

Читать далее

И на Солнце есть пятна

Время на прочтение9 мин
Охват и читатели8.2K

В предыдущей заметке «Планировщик Windows? Это очень просто» было рассказано о технологии получения дизассемблированного текста ядра операционной системы Windows XP образца 2013 года. Такой текст потребовался для анализа и корректировки кода ядра, что позволило изменить политику планирования потоков в Windows и выполнить одну конкретную задачу с уменьшением времени отклика операционной системы.

После решения этой задачи я напоследок просто «полистал» текст ядра, особо не вникая, что именно делается в том или ином участке кода. Хотелось посмотреть, какие приемы локальной (т.е. в пределах 1-2 команд) оптимизации применяет использованный для создания ядра транслятор. Или, может быть, несколько трансляторов, если ядро собрано из нескольких отдельных частей. Сознаюсь, главная цель была в поиске таких приемов генерации кода, которые я не догадался использовать в своем трансляторе.

Поскольку Windows является, наверное, самой дорогой программой в мире по затратам на разработку и сопровождение, уровень качества кода ее ядра должен бы быть одним из самых высоких. Именно поэтому было интересно посмотреть, как устроен код с точки зрения эффективности отдельных команд. Однако я увидел не совсем то, что ожидал и поэтому решил поделиться несколькими соображениями. Для иллюстрации ниже приведены фрагменты дизассемблированного кода ядра Windows XP сборки от 4 июля 2013 года.

Хотя Windows XP и Windows 7 уже, так сказать, «сняты с вооружения», на мой взгляд, изучение даже неподдерживаемых программ имеет смысл. Ядро Windows XP сопровождалось и развивалось около 10 лет. Поэтому на основании анализа кода можно, например, даже прогнозировать пути дальнейшего развития системы. Замечу также, что различия в коде ядер различных версий Windows не так велики как различия некоторых других компонентов.

Читать далее

Микрохирургия ELF'а или «А что, так можно было?!»

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели7.8K

Разбираемся в устройстве PE и рождественских ELF'ов, реверс-инжинирим runtime-библиотеку, портируем ассемблерный код, собираем и редактируем исполняемые файлы и периодически спрашиваем себя "А так можно было?".

Все это на примере обычной задачи портирования компилятора с довольно необычной архитектурой.

Но обо всём по порядку

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