Comments 25
Я просто оставлю это здесь: https://github.com/ganeshkumartk/1line
И проблема с количеством строк больше стоять не будет)
Интересно, ИИ ещё не взялся за написание оптимизирующих компиляторов? Материалу для обучения сколько угодно можно нагенерировать: вот сишный код, вот соответствующий ассемблер.
Я думаю, это очень хорошая статья. Меня интересует такой аспект: допустим у нас есть некоторая виртуальная машина, которая хотела бы оптимизировать подобным образом тот байткод, который подается ей на вход, ради быстродействия (или те его куски, которые являются самыми "горячими"). Выглядит все так, как будто-то бы она могла бы выполнить все необходимые преобразования для этого, разве нет?
Я не очень понимаю вопрос. Ваша виртуальная машина исполняет код, правильно? Ну, сначала она 1) загружает код с диска в память и 2) отображает его в структурах данных, которые позволяют его выполнять. Между этапами 1) и 2) вы можете вставить этап 1.5), который преобразует код, ничто не мешает. Правда, это может занять какое-то время, замедляя запуск программы.
Меня как раз и интересуют возможные аспекты преобразований на этапе 1.5 - особенно в случае ограничений, когда требуется уложить поиск -функций в байткоде и 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 тупеньким, но надёжненьким, а баги в рантайме можно пофиксить обновлением рантайма, а не перекомпиляцией всей той тонны библиотек, которые написали ещё до вашего рождения ©
Если хотите минималистичный оптимизирующий компилятор, очень рекомендую почитать о Sea-Of-Nodes. Начать можно от сюда https://github.com/SeaOfNodes/Simple
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 отвцы программирования (Ахо, Сети, Ульман), мы бы сейчас жили в другом мире.
На гитхабе можно было просто создать новую ветку в том же репозитории
Смогу ли я уложить оптимизирующий компилятор в тысячу строк питона? Прогон первый: mem2reg