Хотите дальше читать devby? 📝
Support us

Facebook переходит на виртуальную машину Java

Оставить комментарий
Facebook переходит на виртуальную машину Java
pay hereД-р Александр Джей Тёрнер – основатель Nerds Central, блога, вебсайта и компании. В одной из своих недавних записей он рассуждает о многоязычной виртуальной машине (так называемой виртуальной машине Да Винчи), а также о том, зачем она таким гигантам, как Facebook и General Motors. «Порочны ли интерпретаторы?» Я задал этот вопрос несколько месяцев тому назад, и скоро он может стать неактуальным. Универсальные интерпретаторы вот-вот разделят судьбу универсальных перфокарт! Facebook ищет способы избавиться от PHP. Почему? Да потому, что каждый процессорный цикл стоит денег. И первым шагом в этом направлении было создание hiphop – кросс-компилятора, преобразующего PHP в C++. Теперь они пытаются компилировать PHP так, чтобы он выполнялся на многоязычной виртуальной машине. Поразителен не столько сам факт присутствия специалистов Facebook на конференции «JVM Language Summit» в Сан-Франциско, сколько их стремление реализовать PHP на виртуальной машине Java при помощи поддержки динамических языков (invoke-dynamic). Главным последствием этого исторического события может оказаться ни больше, ни меньше – полное исчезновение интерпретаторов из мейнстрима универсального программирования. Mlvm (многоязычная виртуальная машина) – это последняя версия JVM. Может возникнуть впечатление, что JSR 292 – запрос на спецификацию, результатом которого и стало появление mlvm – был чем-то малозначительное. А ведь именно благодаря ему был написан небольшой дополнительный байт-код, обеспечивающий поддержку динамических языков. Как же такая мелочь может совершить мировую революцию? Ноль – это, казалось бы, тоже всего ничего. Однако ноль произвел революцию в математике, а значит, и во всем мире... Кстати, изображение нулей в двоичном коде – это на самом деле недоразумение. Алан Тьюринг спроектировал воображаемую модель компьютера без применения нулей, поскольку машине не требуется рисовать овальную линию, чтобы «понять», что «здесь ничего нет». Но, извините, я отклонился от темы. Что же общего между «invoke-dynamic» и нулём? Например, то, что при поддержке динамических языков (функциональность invoke dynamic позволяет динамически вызывать метод без указания типа аргумента) наши возможности на практике значительно расширяются, поскольку многоязычная виртуальная машина позволит сделать с Ruby, PHP, Magik (именно с этой реализацией работаю я) и т.д. то же самое, что V8 позволила сделать с JavaScript. Это значит, что мы берем медленную интерпретируемую систему и обеспечиваем ее компиляцию в машинный код, не теряя при этом никаких преимуществ, присущих исходной интерпретируемой реализации. В частности, процесс сохраняет гибкость и высокую скорость развертывания.

Возможно ли это?

Да, раз уж General Electric как раз над этим работает. Миллионы строк кода, написанные на Magik, уже очень скоро заработают и в версии Magik для mlvm. Технические сложности довольно нетривиальны, но преодолимы, и я очень горжусь, что работаю в команде, занятой решением этих проблем. Если этот проект удастся осуществить с Magik, то с PHP всё будет только проще (поверьте, я знаю, о чем говорю, так как программировал на обоих этих языках. Правила видимости, вычисление выражений и обработка функций первого порядка в Magik организованы гораздо сложнее, чем в PHP).

А насколько быстро это будет работать?

Вначале я и сам в этом сомневался. Но теперь я склоняюсь к мысли, что работать эта система будет всё-таки быстро. Ведь и правда, у нас могут получиться полностью динамические языки в интерпретируемом стиле, которые почти не будут уступать в скорости языку C («почти» в моем понимании значит не более, чем в три раза). А поверить в то, что это возможно, я смог, работая над визуализацией алгоритмов с использованием JavaScript. Ведь в ходе этих тестов JavaScript работал на V8 примерно втрое медленнее, чем чистый язык Java. Итак, в три раза медленнее – это уже не в десятки и не в сотни раз, как в случае со старым интерпретируемым JavaScript. К тому же, не забывайте, что хорошо написанный код на Java работает не медленнее или даже быстрее, чем код на C. Конечно, JavaScript на V8 – это далеко не то же самое, что PHP на mlvm, но принципиальной разницы нет. Действительно, некоторые системы динамической компиляции, применяемые с mlvm, еще довольно «сырые», и их необходимо доработать и/или заменить. Развивать следует и сами практики реализации программ на этой платформе. Но даже на этой ранней стадии разработок я убедился, что выполнение кода можно десятикратно ускорить по сравнению с выполнением в интерпретаторе, основанном на C.

Java 8 – новый предел скорости

В первую очередь следует поменять две вещи. Во-первых, выполнение компиляции указателей следует сделать важной частью динамической компиляции в JVM. Во-вторых, должны совершенствоваться парадигмы кросс-компиляции исходного кода в байт-код. Ключ к эффективному использованию точек вызова функций – в сохранении этих точек мономорфными или с незначительным использованием полиморфизма. Это означает, что на этапе динамического вызова инструкция invoke dynamic внедряется в байт-код, создаваемый из исходного кода. Если сигнатура точки, инициирующей вызов, никогда не изменяется, то эта точка называется мономорфной и может быть скомпилирована в прямой вызов, выраженный в виде машинного кода. Не забывайте, что доступ к этой точке осуществляется во время исполнения, и сама точка может измениться в любой момент: она динамична, как и сам динамический язык программирования. Если через одну и ту же точку диспетчеризации проходит несколько различных сигнатур, то можно задействовать простую структуру в стиле цепочки «if then else». Если точка вызова включает уже больше информации, чем просто несколько сигнатур для обработки, она становится мегаморфной. В подобной ситуации диспетчеризация начинает опираться на поисковые деревья (lookup trees) и хеш-таблицы, и такая структура оказывается более эффективной, чем более стандартные модели интерпретаторов. Правильно организовать диспетчеризацию в таких условиях довольно непросто, особенно в многопоточной среде, но это уже другая история. По мере того, как мы с вами – сообщество программистов – набьем руку на динамическом вызове методов, мы научаемся превращать точки вызова методов в листья на дереве типов. В результате, все больше таких точек становятся мономорфными или незначительно-полиморфными. Может быть, все это слишком технически сложно, но я попытаюсь выразиться иначе. При работе по принципу «invoke-dynamic» динамические языки, диспетчеризация в которых происходит во время исполнения, могут функционировать не менее быстро, чем компилируемые языки, где диспетчеризация происходит во время компиляции. Этот результат достигается благодаря предположению, что вызов, идущий из точки X в точку Y, будет, как правило, относиться к типу А. Но (например) в итераторах вызов из точки X может быть направлен в Y, W, Z и Бог знает куда еще. Эта проблема решается путем перереализации механизма наследования. В результате на смену традиционному наследованию через вызов приходит наследование через копирование. Допустим, P, Q и R являются подтипами Y. Каждый из них имеет один и тот же цикл итератора. В настоящее время традиционная практика наследования в данном случае организуется так: цикл наследуется через вызов. При этом и P, и Q, и R вызывают общий блок кода, определенный в Y и отвечающий за итерацию. Чтобы сделать цикл мономорфным, мы можем перереализовать итерационный цикл, относящийся к P, Q и R. Следовательно, нам (возможно) удастся снизить количество типов, присутствующих в каждом экземпляре цикла итератора. Подобные приемы – и многие другие, которые еще только предстоит изобрести – помогут все ускорять и ускорять выполнение кода в mlvm, и еще одно секретное оружие – лямбда-выражения, применяемые в JVM.

Лямбда-выражения – почему они так важны

Лямбда-выражения чем-то напоминают автоматическую коробку передач. Они упрощают процесс написания кода, но без них вполне можно обойтись. Я довольно подозрительно воспринял их появление в языке Java (правда, во всех моих машинах стоят автоматические коробки передач – и это не случайно). Мне нравится работать с лямбда-выражениями, они – отличное дополнение для C++, например. Но язык C++ уже слишком разросся, чтобы один человек мог в совершенстве знать все его тонкости. Java пока не дошел до такой стадии, этот язык еще не слишком развит... И вот в Java появились лямбда-выражения, которые стали применяться при динамическом вызове методов. Это означает, что производительность одного из ключевых элементов Java будет зависеть от фреймворка для динамического вызова методов. И, следовательно, работа над этим фреймворком в составе JVM просто закипит, пока он не заработает с сумасшедшей скоростью. Пусть такая скорость будет достигнута не сейчас – но уже в обозримом будущем.

Итак, на правильном ли пути находится Facebook?

Да! Неуклонный прогресс Javascript на протяжении последних четырех лет продемонстрировал, насколько высоким потенциалом обладает динамическая компиляция при применении ее в языках, которые еще недавно были сугубо интерпретируемыми. Закономерное постепенное исчезновение случаев «полного переписывания» демонстрирует, насколько непрактичны попытки полного переноса работающей системы с одного языка на другой. Огромная доля кода Facebook написана на PHP, поэтому, было бы очень целесообразно портировать весь этот код на mlvm. К тому же, это должно быть и не так сложно. По моему опыту, полное портирование PHP 5.4 на mlvm должно потребовать не более 6 человеко-лет работы (конечно, если подобрать умелых людей). Такая работа должна строиться на гибридной модели. Оптимальный способ решения проблемы – реализовать простую систему JNI-вызовов от Java к нативному PHP. Уже имеющиеся библиотеки PHP, написанные на языке С, могут при помощи такого механизма вызываться из Java. Java предстоит образовать среду времени исполнения новой реализации PHP. Сам PHP будет компилироваться в байт-код, но при вызове сущности, в роли которой может выступать библиотека на С, вызов пойдет через среду времени исполнения Java к уже имеющейся среде времени исполнения C. Пройдет несколько месяцев или лет, и такие точки «проникающих вызовов», особенно те, которые будут активно использоваться, постепенно удастся портировать с гибридной архитектуры на чистую архитектуру PHP/mlvm. Такой подход предполагает незначительные риски и способен обеспечить для Facebook поступательное наращивание производительности.

Что дальше?

Facebook славно поработал, перенеся важнейшие технологии в область свободного ПО. Поэтому я почти не сомневаюсь, что либо эта компания, либо какая-то другая сможет портировать PHP на mlvm. Аналогичным образом Чарльз Оливер Наттер и его команда поступили с JRuby. Учитывая, что разработка JRuby спонсируется Redhat, а также тот факт, что недавно на работу в Redhat перешел сам Наттер, эсквайр, не вызывает сомнений, что ключевые игроки ИТ-индустрии единодушно поддерживают mlvm. Выгоду такого расклада для специалистов по PHP сложно переоценить. Наступают удивительные времена. Я полагаю, что вскоре интерпретаторы и интерпретируемые языки перейдут в разряд предметно-ориентированных (DSL), а универсальное программирование станет осуществляться в средах с динамической компиляцией, либо с применением предварительной (upfront) компиляции. Это будет благом для компаний, хорошо отразится на производительности и понравится всему миру. Да здравствует JSR 292 и все, кто над ним работал! Источник
Помогаете devby = помогаете ИТ-комьюнити.

Засапортить сейчас.

Читайте также
Соцсеть на мели: Meta хочет больше платных функций в Facebook, WhatsApp и Instagram
Соцсеть на мели: Meta хочет больше платных функций в Facebook, WhatsApp и Instagram
Соцсеть на мели: Meta хочет больше платных функций в Facebook, WhatsApp и Instagram
1 комментарий
Meta полностью прекратит поддержку приложения Facebook Gaming
Meta полностью прекратит поддержку приложения Facebook Gaming
Meta полностью прекратит поддержку приложения Facebook Gaming
Цукерберг: сотрудники Facebook влияли на выдачу рекомендаций в ленте соцсети
Цукерберг: сотрудники Facebook влияли на выдачу рекомендаций в ленте соцсети
Цукерберг: сотрудники Facebook влияли на выдачу рекомендаций в ленте соцсети
1 комментарий
На Facebook из-за ошибки любой мог разместить пост на популярных страницах — их завалило спамом
На Facebook из-за ошибки любой мог разместить пост на популярных страницах — их завалило спамом
На Facebook из-за ошибки любой мог разместить пост на популярных страницах — их завалило спамом

Хотите сообщить важную новость? Пишите в Telegram-бот

Главные события и полезные ссылки в нашем Telegram-канале

Обсуждение
Комментируйте без ограничений

Релоцировались? Теперь вы можете комментировать без верификации аккаунта.

Комментариев пока нет.