Движок V8 и браузер Google Chrome станут лучше поддерживать Asm.js

    Около двенадцати часов назад Джон Резиг нащебетал в Твиттер, что на конференции Google I/O было объявлено об улучшении поддержки Asm.js в движке V8 и во браузере Google Chrome.

    Так как про Asm.js упоминали на Хабрахабре (1, 2), то достоинства его могли стать известны многим читателям. Тем приятнее им предвкушать теперь в самом скором времени появление этих достоинств не только во браузере Firefox (где они впервые были внедрены Фондом Мозиллы), но и в движке V8 (а значит — и в построенном на его основе движке Node.js!), и во браузере Google Chrome.

    Но для тех читателей, которые до сих пор пропускали эту новинку мимо себя, я также вкратце напомню суть. Asm.js это особое подмножество языка JavaScript: ограничившись им в своём скрипте, автор скрипта обеспечивает возможность оптимизации интерпретируемого кода не только в момент исполнения (just-in-time, JIT), но даже и заблаговременно (ahead-of-time, AOT), то есть такому джаваскрипту становится возможно один раз однозначно заранее поставить в соответствие некоторый машинный код. Эффект этот достигается ценою заметных усилий по самоограничению. (В частности, при помощи операции «|0» и других подобных специальных приёмов тип значения каждого входного параментра функции, равно как и выходного значения, оказывается однозначно заданным и неизменным.) Зато его итогом становится небывалый рост скорости исполнения джаваскрипта — теперь по скорости он уступает скомпилированной программе (на Си или Си++) не более чем в два раза.

    Основное направление практического применения Asm.js лежит даже не в области ручного программирования (при котором сознательное соблюдение ограничений Asm.js может оказаться неприемлемо тягостным для программиста), а в области полностью автоматической транскомпиляции (перевода на язык JavaScript с других языков программирования) целого ряда достаточно сложных программ и библиотек, которые становятся благодаря этому не менее кросс-платформенными, чем сам JavaScript. В качестве средства такой транскомпиляции наиболее известен Emscripten, а отчасти также и Mandreel.

    Мы стоим на пороге такого будущего, в котором очень многие программы из числа работающих с командною строкою (не требующих GUI) можно будет немедленно сделать кросс-платформенными (Node.js обеспечит их исполнение на Windows, Mac OS X и Linux), для чего достаточно будет скомпилировать их в JavaScript (при помощи LLVM и затем Emscripten) вместо машинного кода — и вдвое пожертвовать скоростью исполнения их.

    Впрочем, впечатляющие примеры на странице Emscripten наглядно показывают, что переносу поддаются и некоторые такие графические приложения, которые способны работать через EGL вместо конкретного графического API (OpenGL, или OpenGL ES, или OpenVG). Правда, таким приложениям Node.js не будет достаточно — потребуется перенос их в Паутину, то есть исполнение приложений во браузерах. Firefox и присоединившийся к нему в поддержке Asm.js браузер Google Chrome станут исполнять их с вышеозначенною небывалою быстротою. Но нетрудно предвидеть, что и все остальные браузеры (IE, Opera, Safari и так далее) также смогут исполнять их невозбранно (потому что Asm.js — это подмножество обыкновенного JavaScript); единственная разница будет в скорости исполнения.
    Поделиться публикацией

    Комментарии 49

      +11
      Есть надежда, что это повлияет на safari/opera+webkit?

      p.s. Мицгол, я каждую вашу заметку как повесть читаю. Красиво написано.
        +4
        Очевидно же в Opera это будет.
          +1
          Как только Opera перейдёт на V8. (Планы такого перехода оглашены.)
          +2
          Очевидно, что давление на Apple (как на производителей Safari) и на Microsoft (как на производителей IE) усилится, им придётся либо что-то делать, либо мириться с тормозами результатов выполнения транскомпилированных программ и библиотек в своих браузерах. Так что надежда есть.

          В отношении Opera место надежды занимает уверенность (Opera в феврале начала переходить на V8). Нет только ясности: Бог его знает, когда они окончательно перейдут на V8 и выпустят Opera 14.
            0
            А почему Opera 14? Тринадцатой же еще нет, вроде бы
        +2
        На десктопах производительность браузеров и так достаточна. А вот на мобильных устройствах всё куда печальнее: мало где можно заставить Canvas выдавать больше 3 FPS, а уж про WebGL можно даже не заикаться, столь мизерная у него производительность. И, боюсь, asm.js здесь не поможет, т.к. тормозит сама отрисовка.
        Плюс на HTML5 до сих пор нельзя сделать кроссбраузерные эмуляторы старых приставок, т.к. всё ещё нет нормального API для синтеза звука (пока что тут WebKit впереди всех, остальные сильно отстали).
          +1
          Понимаю, что речь в вашем посте идет о мобильных браузерах, но как обстоят дела с производительностью у Firefox OS? Там по идее порт настольной версии Firefox и все должно работать быстро.
            +2
            По ощущением, немного тормозней, чем Firefox fo Android, но это отношу на то, что на андроиде у меня 1 гиг, а на Firefox OS — 512.
            Если вас интересуют конкретные тесты, пришлите ссылки, я в субботу прогоню их на Geeksphone Peak
              0
              Отправил вам в пятницу ссылки — пишу здесь, вдруг не заметили.
                +1
                Простите, не сделал :-(
                У меня отмечено в почте, доберусь — сделаю.
                  +2
                  Напоминаю. Geeksphone Peak только у вас у одного в России!
            +1
            А вот на мобильных устройствах всё куда печальнее: мало где можно заставить Canvas выдавать больше 3 FPS

            Ну тут вы перегибаете. Начиная с iOS5 и Android4 можно делать вполне играбельные приложения.
              0
              Ага, и с записью звука там тоже все печально.
                +2
                Если вы про Web Audio API, оно вскоре появится в Firefox wiki.mozilla.org/WebAudio_API_Rollout_Status
                  +1
                  И можно даже дополнительно сообщить, что здесь «вскоре» означает «не более чем через три месяца», потому что именно такой срок отделяет Aurora-версию от официального выпуска.
                    0
                    Я бы не стал давать таких обещаний за разработчиков. :-)
                      0
                      Тем не менее именно такой срок соблюдался ими довольно неуклонно, почти два года кряду — с лета 2011 года.
                        +1
                        Я бы не стал давать обещаний на тему того, что конкретно будет в какой версии.
                        Легко могут обнаружится баги, и включение поддержки будет перенесено на следующую версию.
                          0
                          А, вот Вы о чём.
                  +3
                  Достаточно, говорите? Посмотрите быстро ли работает у вас PDF.js. У меня на больших документах — со скрипом.
                  0
                  В частности, при помощи операции «|0» и других подобных специальных приёмов тип значения каждого входного параметра функции, равно как и выходного значения, оказывается однозначно заданным и неизменным.


                  Одна из основных фишек js — нетипизированные параметры, и я так понял такие функции не поддадутся оптимизации в принципе.
                  Не получится так, что расплатой за скорость будет потеря удобства и робастности кода?
                  Т.е. код будет менее универсальным, но более быстрым, а надо ли?
                    +4
                    Asm.js — это дополнительная возможность оптимизации, которую можно (а можно и не) использовать. Если не нравится, можно использовать классический VanillaJS с прежней скоростью.
                      +3
                      asm.js не предназначен для ручной оптимизации кода.
                      Он предназначен для компиляции в JavaScript с других языков (например C) при помощи Emscripten.

                      Впрочем, даже сейчас Javascript JIT активно угадывает тип используемых переменных. Возьмем функцию
                      function increase(number)
                      {
                        return number + 1; // Медленное сложение, т.к. тип аргумента неизвестен.
                      }
                      var num = 0;
                      for (var i =0; i < 1000000; i++)
                      {
                        num =  increase (num); // Это горячая функция, по статистике аргумент всегда int
                      }
                      

                      JIT-компилятор превратит функцию increase примерно в такой псевдокод
                      function increase(number)
                      {
                        if (number is not integer)
                        {
                          Singal type inference error // Возврат в медленный режим (самый простой вариант — просто убрать эту оптимизацию)
                        } 
                        return number + 1; // Быстрое целочисленное сложение
                      }
                      


                      Идея asm.js в том, чтобы раскидывать подсказки для JIT-компилятора.
                      function increase(number)
                      {
                        number = number | 0; // Битовый OR точно вернет integer, а в процессе оптимизации эту инструкцию можно выкинуть.
                        return number + 1; // Быстрое целочисленное сложение
                      }
                      


                      Если внутри файла в нужных местах сгенерированы подсказки, то компилятор может проверить, что все будет ок, в момент разбора файла, и ему не надо будет раскидывать по сгенерированному коду инструкции типа «если тип не угадал, перекомпилим-ка функцию заново».
                        0
                        Я понимаю, что не для ручной.
                        Я имею ввиду немного другое.
                        В моих веб проектах часто встречаются параметры функций априори имеющие несколько возможных типов.
                        Взять к примеру, тот же самый Ext Js, где ширина может быть инициирована числом или строкой.
                        В конструкторе параметр проверяется с помощью instanceof либо typeof и на этом выстраивается дальнейшая логика работы.

                        А по поводу приведенного вами примера с детерминированными функциями, тут я полностью согласен, их оптимизировать — одно удовольствие :-) Только, я вот не знаю как у вас, в моих проектах таких минимум.
                        И говоря о том что, мы будем работать лишь в 2 раза медленней с++, я б добавил, что на сервере — возможно да, тут я всеми руками за, а на клиенте с тяжелой веб мордой, извините — вряд ли.

                        Если только найдутся особо ретивые бойцы которые начнут руками молотить код, чтоб он подходил под оптимизацию.
                        Но это вряд ли кому будет нужно, если только письками скоростью мериться. Проще заказчику объяснить что 1Гб оперативы мало и все.
                          0
                          Фрагмент кода, защищённый инструкцией instanceof по сути мало чем отличается от фрагмента кода, защищённого инструкцией |0.
                          И в том, и в ином случае тип доподлинно известен. Учитывает ли это конкретный движок JS — другой вопрос.
                      0
                      Там дальше разъясняют, что не добавили поддержку, а просто увеличили производительность на бенчмарке asm.js.

                      Кстати, как альтернативное мнение о asm.js (с которым я согласен) можно почитать замечательную статью от одного из разработчиков V8:
                      mrale.ph/blog/2013/03/28/why-asmjs-bothers-me.html
                        0
                        Вячеслав есть здесь на Хабре, поэтому можно попробовать призвать его в тред :)
                        mraleph
                          +2
                          Прелюбопытно видеть, что mraleph во Твиттере щебечет: оказывается, рост производительности V8 при выполнении кода asm.js является не результатом поддержки директивы "use asm" и не последствием внедрения AOT (которого не было и в помине!…), а просто итогом нескольких оптимизаций общего характера, внесённых в движок V8 и оказывающих влияние на весь JavaScript в целом.

                          Похоже на то, что я напрасно и чрезмерно был увлечён энтузиазмом Резига, господа читатели.
                            0
                            Впрочем, рано вешать нос; дождёмся публикации результатов каких-нибудь новейших испытаний скорости выполнения тестов Asm.js. А не то вдруг там и впрямь заметный рост производительности V8, хотя и без AOT.
                              +1
                              на наборе микробенчмарков V8 стал в среднем в 2-3 раза быстрее, на каких-то показывая скорость эквивалентную той, что дает Mozilla-вский AOT. однако еще много работы впереди. если вы напишите asm.js, который на V8 почему-то работает медленно — обязательно засылайте его в code.google.com/p/v8/issues/entry
                          +1
                          вообще это два разных бага.
                          code.google.com/p/v8/issues/detail?id=2599 — добавить поддержку asm.js
                          code.google.com/p/v8/issues/detail?id=2424 — тот, про который вы говорите.
                            +1
                            2424 это лишь один из многих. 2223, 2513, 2618, 2678, и т.д. Многие уже починены, но почему-то не закрыты: skinning например сейчас в пределах 5% от показателей OdinMonkey и >3x быстрее чем голый Ion Monkey, при этом V8 не полагается на «use asm» чтобы достичь таких результатов.
                          +1
                          Меня вот давно интересует, зачем все упираются в javascript с такими костылями, хотя можно было бы все организовать по принципу .net, стандартизировать байткод (его подмножества для такого случая) и библиотеки, и позволить пользоваться любым языком. Ведь javascript для многих не самый желанный язык.
                            +2
                            Учитывая современные тенденции по созданию трансляторов из чего угодно в JS, в скором времени JS и станет таким стандартизированным «байткодом».
                            И будут холивары в стиле «да что ты пишешь на этом тормозном %Lang_name%, написал бы нормально, на JS++» ).
                              –1
                              код жс — это текст, байткод — бинарный
                                0
                                Ну почему же.

                                Текст — это тоже байты.

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

                                Например, представим, что в байткоде есть инструкция AddL и 10 регистров, адресующихся в формате rXrX. Тогда вполне нормальный кусок текста AddLr0r1 является struct {long instruction; char leftSource; char leftOffset; char rightSource; char rightOffset;}, где из leftOffset и rightOffset вычитается 48.
                              0
                              да это странный подход немного, видно из-за обратной совместимости js останется навсегда с нами.
                              asm.js больше похож на временный костыль, но хватит ли сил его убрать неизвестно.

                              — и меня уже притомляют маркетинговые названия…
                                +1
                                Логичный шаг дальше — написать на asm.js интерпретатор байт кода и постепенно реализовавывать нативную поддержку этого байткода в браузерных движках.
                                +1
                                Видимо в силу того что он есть в каждом браузере. А браузер есть почти на каждом телефоне\планшете\ноутбуке\компьюторе.
                                  +10
                                  компьюторе
                                  компьюторе
                                  компьюторе
                                  [Staredad]
                                +4
                                А почему «во браузере», но при этом «в движке»?
                                  +5
                                  Обычная безграмотность, не обращайте внимания.
                                    –3
                                    Ошибаетесь.

                                    Есть правило, в соответствии с которым я действую.

                                    Нет правил, нарушаемых этими словосочетаниями.
                                    0
                                    Здесь эта форма предлога является стилистическим приёмом для придания торжественности тексту. (Подробности см., например, вон там: Розенталь Д. Э., Джанджакова Е. В., Кабанова Н. П., «Справочник по правописанию, произношению, литературному редактированию», глава XLV, §199, пункт 9, подпункт 4.)

                                    Употреблять этот приём я могу, разумеется, не только неуклонно, но и выборочно, по своему вкусу.

                                    Приём же этот служит как один из способов, необходимых для создания впечатления «красиво написано» — подобного тому, которое nick4fake испытал и выразил выше.
                                      0
                                      Лично у меня от такой стилистики складывается впечатление, что вы описываете технологии которым уже минимум лет 100) Ну и как определить можно ли употребить сей торжественный предлог со следующим словом или нет. Например «во дни сомнений» звучит еще более менее, а вот «во пасти безумия», к примеру, совсем слух режет. Я так понимаю четкого правила на этот счет нет?
                                        0
                                        «Во» выглядит не особенно приемлемо, когда следующее слово начинается единственным согласным перед нередуцированным гласным звуком. (Обобщение закона Гавлика на предлоги.)
                                          +1
                                          Интересно, спасибо.
                                      • НЛО прилетело и опубликовало эту надпись здесь

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                    Самое читаемое