Недавно мы написали статью про поддержку WebGL в Unity. В ней мы кратко рассказали о том, как будут работать скрипты в WebGL с использованием новой технологии IL2CPP. Однако IL2CPP — это нечто гораздо более масштабное, нежели просто новое решение для скриптов в WebGL, это наша собственная, высокопроизводительная реализация .Net Runtime, которая будет выпущена на многих платформах.
Но перед погружением в будущее стоит поговорить о настоящем.
Скрипты в Unity сегодня
Мы используем Mono (и WinRT для приложений Windows Store и Windows Phone) чтобы привнести в Unity простоту использования C#, доступ к сторонним библиотекам и практически двоичное быстродействие. Но есть несколько сложностей:
— быстродействие среды исполнения C# все еще уступает C/C++
— последние и лучшие возможности языков и среды исполнения .Net не поддерживаются версией Mono, используемой сейчас в Unity
— с примерно 23 платформами и вариантами архитектуры требуется очень много усилий на перенос кода и поддержку его качества на одинаковом уровне
— сборка мусора может вызвать задержки при выполнении
Последние несколько лет мы постоянно думали о том, как справиться со всем этим. Одновременно шли исследования в области поддержки скриптов для WebGL. По мере продвижения в обоих направлениях они слились в один подход.
Осознав масштаб проблемы, мы начали экспериментировать с разными путями ее решения. Некоторые из них были многообещающими, некоторые нет. Но в итоге мы нашли новаторский путь решения наших проблем.
Это IL2CPP
IL2CPP: быстрое и короткое введение
IL2CPP состоит из двух частей: Ahead of Time (AOT) компилятора и виртуальной машины (VM)
Они являются нашей реализацией Common Language Infrastructure, схожей с .Net и Mono. Она совместима с текущей реализацией скриптов в Unity.
Ее основное отличие от текущей реализации в том, что IL2CPP компилятор преобразует сборки в исходный код C++. Затем он использует стандартный компилятор C++ для данной платформы, чтобы создать родные двоичные файлы.
Код выполняется одновременно с дополнительными службами (вроде сборщика мусора, метаданных, специфичных для платформы ресурсов), которые обеспечивает IL2CCP VM.
Преимущества IL2CPP
Давайте рассмотрим каждую из вышеупомянутых сложностей и то, как как с ней справляется IL2CPP.
Производительность
В IL2CPP мы стремимся совместить простоту использования и скорость написания кода со производительностью C++.
С ним мы можем сохранить скорость текущего процесса написания скриптов и дополнить ее моментальным повышением производительности. Мы видели 2-3-кратное увеличение скорости выполнения некоторых наших тестов со сложными скриптами. Такой прирост производительности возникает по нескольким причинам:
— Компиляторы и компоновщики C++ дают нам большое количество ранее недоступных методов оптимизации.
— Ваш код подвергается статическому анализу и на скорость и на размер
— Unity-ориентированные оптимизации среды выполнения скриптов
И хотя работа над IL2CPP еще далека от завершения, этот ранний прирост производительности однозначно указывает на большое будущее нашего проекта.
Обновление .Net
Мы очень часто получаем запросы на обновление среды выполнения. В последние годы .Net очень быстро развивался, а Unity на данный момент поддерживает только функционал эпохи .NET 2.0/3.5 как для компилятора C# так и для сторонних библиотек. Многие пользователи запрашивали доступ к новым возможностям как для своего кода так и для сторонних библиотек.
По мере взросления IL2CPP мы будем обновлять версии компилятора Mono C#, базовых библиотек классов и среды исполнения для редактора (редактор не будет переводиться на IL2CPP, чтобы сохранить скорость разработки скриптов). Сочетание этих двух процессов привнесет современную версию .Net в Unity.
Стоит отметить, что мы сотрудничаем с Microsoft, чтобы гарантировать качество и стабильность при добавлении текущих и будущих возможностей .Net в Unity.
Переносимость и поддержка
Хотя это может показаться внутренними проблемами Unity, они так же касаются и вас. Виртуальная машина Mono содержит огромное количество кода, специфичного для конкретной платформы и архитектуры. При переносе Unity на новую платформу мы тратим очень много сил на перенос и поддержку Mono VM для этой платформы. Некоторые особенности (и ошибки) могут существовать только на отдельных платформах. Это затрагивает те ценности, которые пытается обеспечить для вас Unity — простоту переноса контента между платформами.
IL2CPP решает эту проблему несколькими путями:
— Код конвертируется в C++, а не специфичный для данной архитектуры машинный код. Стоимость переноса и поддержки генерации кода для каждой конкретной архитектуры заметно снижается
— Разработка новых возможностей и исправление ошибок заметно ускоряются. Для нас дни ковыряния в архитектурно-специфичном коде заменяются минутами правки C++. Новые возможности и исправления ошибок сразу доступны для всех платформ. Нынешний вариант IL2CPP очень быстро переносится на новые платформы.
В дополнение к этому, специфичные для платформы или архитектуры компиляторы обычно оптимизируются гораздо лучше, чем один-единственный генератор кода. Это позволит нам повторно использовать все те усилия, которые пошли на разработку C++ компиляторов, не переизобретая их заново внутри компании.
Сборка мусора
IL2CPP не привязан к какому-то конкретному сборщику мусора, вместо этого он подключает их через специальный API. Нынешний вариант IL2CPP использует усовершенствованную версию libgc, хотя мы рассматриваем разные варианты. Одновременно с этим мы исследуем возможности сокращения давления со стороны GC с помощью анализа, выполняемого в компиляторе IL2CPP.
Хотя на данный момент нам нечего больше рассказать, исследования продолжаются. Мы знаем, что это важно для вас, так что продолжим работу и будем информировать вас о ней в будущих записях. В контексте сборки мусора стоит заметить, что независимо от IL2CPP, в Unity 5 вы увидите намного больше свободных от выделения API (allocation free API).
Чем не является IL2CPP
IL2CPP не является попыткой воссоздать всю среду .Net или Mono. Мы продолжим использовать компилятор C# из Mono (а в будущем возможно и Roslyn). Мы продолжим использовать библиотеки классов Mono. Все имеющиеся на данный момент возможности и сторонние библиотеки, совместимые с Mono AOT будут работать и с IL2CPP. Мы собираемся заменить только Mono VM и AOT компилятор, продолжая использовать замечательный проект Mono.
Когда я смогу попробовать IL2CPP?
Мы надеемся, что к данному моменту возможность попробовать IL2CPP волнует вас так же сильно как и нас, и вы задаетесь вопросом — когда вы сможете опробовать его лично? Ранняя версия IL2CPP будет частью поддержки WebGL в Unity 5.
После WebGL мы продолжим разработку IL2CPP для других платформ. На самом деле у нас уже есть реализации для целого ряда поддерживаемых нами платформ. Мы рассчитываем выпустить как минимум еще одну платформу в этом году. На данный момент мы планируем сделать iOS следующей платформой с поддержкой IL2CPP.
Запланированное обновление среды Mono произойдет после того, как IL2CPP будет поддерживаться на большем количестве платформ и немного повзрослеет.
Единственная платформа, которая никогда не будет поддерживать IL2CPP — это WebPlayer, из-за ограничений, связанных с безопасностью. Как и было отмечено ранее, редактор продолжит работать на Mono.
Вы можете увидеть среду выполнения IL2CPP в действии прямо сейчас. Две демонстрации WebGL, которые мы размещали ранее, работают именно на нем.
Что дальше?
Мы продолжаем усердно работать над IL2CPP: добавляем новые возможности, оптимизируем генерацию кода, исправляем ошибки и добавляем поддержку новых платформ. Мы будем публиковать более подробные статьи по мере продвижения нашей работы и продолжим обсуждать ее с вами на форумах.
Команда скриптов Unity.
Небольшое дополнение из ответов разработчиков на вопросы в англоязычных комментариях и специальной теме на форуме Unity:
Термин «виртуальная машина» может быть немного обманчивым. На самом деле не будет никакой настоящей виртуальной машины, все будет в двоичном коде, но будет ряд функций, доступных во время выполнения и реализующих функциональность, необходимую управляемому коду, вроде системных служб или сборки мусора, которые мы и называем в данном случае виртуальной машиной.
***
Написание скриптов на C++ не является официальной целью IL2CPP и в ближайшее время ничего подобного не появится, хотя это и может произойти когда-нибудь в будущем как побочное следствие принятых решений.
***
Исходные коды пока не будут открываться, мы долго обсуждали подобную возможность и пока не приняли подобного решения. В открытии исходников есть как преимущества для нас, так и недостатки, так что для принятия столь серьезного решения должны быть веские причины.
***
Ограничения на динамическую генерацию кода полностью аналогичны ограничениям в Mono AoT, совместимый с ним код будет работать с IL2CPP. Reflection будет работать. Вещи вроде System.Reflection.Emit нет. Никакой динамической генерации кода во время выполнения.
***
iOS будет первой платформой с поддержкой IL2CPP потому, что там уже используется AoT, так что переход будет более плавным. Потом будет поддержка остальных платформ включая PC, Mac и Linux.
***
Из-за AoT и ограничений LGPL мы не можем использовать Mono на iOS, что не дает нам обновить версию Mono для редактора и других платформ
***
Я не юрист. Точно не юрист. Но по поводу юридических ограничений связанных с Mono и LGPL могу сказать следующее. Проблема не в компоновке, можно сделать компоновку обеспечив пользователей дополнительными данными (object files). Проблема в том, что ограничения коснутся всех наших клиентов, делающих игры и приложения на Unity. Они тоже попадут под ограничения LGPL будут вынужденны предоставлять обьектные файлы всем своим клиентам. Еще раз отмечу что я не юрист, это не является официальной позицией Unity и всего лишь отражает мое понимание ситуации как программиста и все в таком духе.
***
С Mono нам приходилось держать команду специалистов для каждой новой платформы. Если Mono не поддерживал эту платформу, нам приходилось выполнять просто огромный объем работы, так как по сути дела нам приходилось с нуля писать свои собственные средства JIT для каждой платформы. Для некоторых платформ мы тратили на перенос Mono в три раза больше сил, чем на всю остальную работу. С IL2CPP вместо написания средств JIT мы сможем просто использовать существующий компилятор C++, это намного проще.
***
Я работал над Mono 9 лет и могу точно сказать, что перенос Mono на новую платформу требует примерно года работы настоящего эксперта и по Mono и по данной платформе, если вы вообще сможете такого найти и удержать его для добавления всех возможностей, требующих реализации, специфичной для данной платформы. Сложно описать словами, как рады наши наши специалисты по платформам новой технологии. Они торгуются за право генерировать, отлаживать и поддерживать код сборок в С++. В записи должны были упомянуть, что портирование теперь занимает дни, вместо месяцев и лет. Как мне кажется многие двигаются в этом направлении. Мы начали работу до того, как Microsoft анонсировала .Net Native, но это только подтверждает верность выбранной нами стратегии. Немного ограничив возможности во время выполнения (никакой динамической генерации) вы получаете массу преимуществ. Никто не заставляет вас использовать это для самостоятельных приложений на PC. Они получат обновленную версию Mono вместе с редактором, как только IL2CPP станет достаточно стабильным на платформах с AoT. Главная цель IL2CPP — это те платформы, где AoT действительно имеет смысл.
***
Мы понимаем, что вовсе не скрипты обычно являются узким местом в плане производительности, обычно проблемы возникают в случае неправильных или плохих скриптов. Нам никто еще не жаловался не слишком медленное выполнение методов C#. Сборка мусора отдельный разговор, оставим его на потом. Но люди любят обсуждать производительность. Как мне кажется IL2CPP во многих случаях сделает осмысленным использование скриптов для тех вещей, которые раньше считались слишком тяжелыми и выполнялись в C++. ИИ, физика и все в таком духе ускорится сильнее всего и появятся новые, интересные возможности.
Лично я могу сходу вспомнить следующие оптимизации
— отказ от проверки границ массивов
— устранение поддержки исключений (нагрузка от них различается в зависимости от платформы)
— устранение статической инициализации, сейчас при каждом создании экземпляра или обращении к статическому методу/свойству требуется требуется проверить, что для всех типов со статическим конструктором он был выполнен
— поддержка SIMD
— оптимизация взаимодействия между двоичным и управляемым кодом. Мы постараемся выполнить ее по максимуму и скорее всего дадим вам возможность усиливать ее, добровольно согласившись на дополнительные ограничения
Все это случайный список того, что вспомнилось мне прямо сейчас. Позже мы опубликуем более подробную информацию.
***
Unity не поддерживает возможность создания модов к игре и не поддерживает возможность создания патчей. Сейчас у нас есть сторонние решения, позволяющие нам подгружать моды из дополнительных .Net dll (правда патчи так все равно не сделаешь). Но с IL2CPP мы не сможем делать и это.
На Mac/Linux/Windows и в редакторе мы будем поддерживать Mono как один из вариантов еще очень и очень долго и через какое-то время обновим его на новую версию. Так что если вы делаете игру с поддержкой модов для этих платформ, то сможете и дальше использовать Mono. Никаких проблем. Перекрестная публикация для Mac / Linux / Win так же продолжит работать без изменений.
На других платформах вроде iOS и приставок Unity уже использует Mono AoT, таким образом загрузка dll и так невозможна и никогда не станет возможной из-за ограничений самих платформ. Здесь вы ничего не потеряете.
Автор: Vedomir