Pull to refresh

Comments 25

Интересно, ИИ ещё не взялся за написание оптимизирующих компиляторов? Материалу для обучения сколько угодно можно нагенерировать: вот сишный код, вот соответствующий ассемблер.

Любое преобразование кода, которое может сделать компилятор, должно доказуемо быть эквивалентным. Со словом "доказуемо" у ИИ пока тяжело. С другой стороны, LLM уже применяют к coq, так что поживём - увидим.

Я думаю, это очень хорошая статья. Меня интересует такой аспект: допустим у нас есть некоторая виртуальная машина, которая хотела бы оптимизировать подобным образом тот байткод, который подается ей на вход, ради быстродействия (или те его куски, которые являются самыми "горячими"). Выглядит все так, как будто-то бы она могла бы выполнить все необходимые преобразования для этого, разве нет?

Я не очень понимаю вопрос. Ваша виртуальная машина исполняет код, правильно? Ну, сначала она 1) загружает код с диска в память и 2) отображает его в структурах данных, которые позволяют его выполнять. Между этапами 1) и 2) вы можете вставить этап 1.5), который преобразует код, ничто не мешает. Правда, это может занять какое-то время, замедляя запуск программы.

Меня как раз и интересуют возможные аспекты преобразований на этапе 1.5 - особенно в случае ограничений, когда требуется уложить поиск \phi-функций в байткоде и mem2reg в ограниченное время/память, чтобы оптимизация не приводила к подвисанию обработки: например можно рассмотреть задачу работы оптимизирующей виртуальной машины на микроконтроллере во время того как оный занимается проигрыванием музыкального трека - я не хочу слышать задержки в музыке, что, наверное, потребует поиска каких-то компромиссов чтобы ограничить скоуп, в котором мы делаем mem2reg (особенно когда этот скоуп содержит в себе много базовых блоков). Т.е. мы не можем построить CFG для всей программы сразу, а как сьесть слона по частям я себе не очень представляю...

Поздравляю, вы только что изобрели Java (ну, точнее hotspot vm, которую имеют ввиду, когда говорят о jvm)

Я в последний раз джаву трогал, когда она была в версии 4, так что не кидайте в меня тапками :)
А разве жавамашина оптимизирует уже готовый байткод? Какой в этом смысл? Не проще эту задачу сложить на javac?

Нет, javac это как clang (без дальнейшего куска с llvm) - переводит java код в промежуточный байткод, делая это максимально наивно и просто. Все оптимизации делаются в рантайме.
Зачем? В рантайме больше информации о куске кода (мы ведь его уже запустили пару-тройку тысяч раз в интерпретаторе), можно лучше соптимизировать. В хотспоте в целом два оптимизирующих компилятора, C1 (иногда именуемый клиентским), который не очень то и сильно оптимизирует, зато делает это быстро, и если метод совсем уже горячий, то тут уже подъезжает C2, серверный компилятор, он уже все кишки выворачивает этим вашим фибоначчам, жрет как конь правда.

Опять же, это всё относится к классическому хотспоту, есть AOT компиляция в граале и андроиде, есть чистые интерпретаторы, и так далее по списку.

Ну логично, динамический анализ. Собрать статистику с кода и преобразовывать в соответствии с ней.

Ну, да, только это ответ на вопрос "почему jit".
А если вопрос ставить как "а чё сам javac простые случаи не соптимизирует, ну тут же даже школьнику понятно, что можно так-то так-то, это ничего никогда не сломает" - то бабка у подъезда слышала от внука, который знаком с подружкой инженера Sun, что это принципиальное решение, дабы не внести случайно баги в javac, с последствиями которых надо будет возиться во всееееех последующих версиях jvm, причём не только в хотспоте, а вообще всем существующим jvm машинам, ведь они все должны переваривать тот бажный байткод, который javac навалил в java 1.1, и вот мы волосы рвём как нам плясать вокруг этого мамонта. Проще оставить javac тупеньким, но надёжненьким, а баги в рантайме можно пофиксить обновлением рантайма, а не перекомпиляцией всей той тонны библиотек, которые написали ещё до вашего рождения ©

ssloy@periwinkle:~/tmp/Simple$ cloc src/
     158 text files.
     154 unique files.                                          
       4 files ignored.

github.com/AlDanial/cloc v 1.98  T=0.14 s (1064.3 files/s, 142314.1 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Java                           154           2539           3110          14944
-------------------------------------------------------------------------------
SUM:                           154           2539           3110          14944
-------------------------------------------------------------------------------

Ох, не назвал бы я 15к строчек минималистичным... Но за ссылку спасибо.

Примеров там как раз очень мало, и они в другой папке, вы в репозиторий-то загляните. Джава да, но не в пятнадцать же раз. Особенно учитывая, что они как раз нормального синтаксического дерева не имеют, парсер тупой однопроходный. То есть, они и так пытались экономить как могли, но всё равно получился огромный код.

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

Был неправ, тесты действительно захватил

ssloy@periwinkle:~/tmp/Simple/src/main$ cloc .
     121 text files.
     121 unique files.                                          
       0 files ignored.

github.com/AlDanial/cloc v 1.98  T=0.11 s (1064.1 files/s, 108766.8 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Java                           121           1805           2385           8178
-------------------------------------------------------------------------------
SUM:                           121           1805           2385           8178
-------------------------------------------------------------------------------

На самом деле и это тоже не самая точная цифра, ибо там тесты местами интрузивные типа:

public static final Field TEST = make("test",Type.NIL,-2,false);
public static final Field TEST2= make("test",Type.NIL,-2,true);

Плюс всякие утилиты типа IR Printer, JSViewer и тд. Именно очищенный компилятор там наверняка ещё меньше. Плюс в каждой главе я так понимаю там по своему дубликату кода компилятора лежит. Хотя с вашим логом консоли непонятно откуда конкретно вы замеряете, ибо на бранче main там src появляется с уровня глав, а у вас он от корня репы появляется как-то.

То есть, они и так пытались экономить как могли, но всё равно получился огромный код.

Собсна, поэтому и писал изначальный комментарий - Java довольно вербозная сама по себе. А вот про однопроходность не понял в чем минус - линейный проход с тривиальными оптимизациями быстрее и проще в SoN, нежели беготня по AST. Конечно, и там и там есть свои плюсы и минусы.

Вы еще тесты посчитали. Но все равно если сравнивать с LLVM и GCC, то это не о чем. На самом деле этот проект - выжимка из HotSpot C2 (от автора). Так что идеи вполне работоспособные (и красивые).

Хотя для обучения, LLVM с класическими алгоритмами может и предпочтительней.

Будет время/желание, взгляните на мой проект https://github.com/dstogov/ir (отимизатор и JIT коде-генератор). Буду длагодарен за feedback.

Питушман придаёт пряности статье. Если бы на нём начинали учить IT отвцы программирования (Ахо, Сети, Ульман), мы бы сейчас жили в другом мире.

Sign up to leave a comment.

Articles