Больше всего Microsoft известна как разработчик Windows и, как правило, чаще всего эту ОС упоминают в связке с чипами Intel или AMD. Многие бы удивились, пишет Мэри Бренском на портале ZDNet, узнав, что Windows работает на значительно большем количестве процессорных архитектур — PowerPC, Alpha, Itanium, MIPS, а в 2009 г. Microsoft запустила внутренний проект для запуска Windows 7 на ARM. Он ориентировался на 32-разрядные процессоры ARMv7 с поддержкой технологии VFP (Vector Floating Point), являющейся расширением сопроцессора в архитектуре ARM, наборами инструкций NEON (ARM-версия SSE-инструкций Intel для параллельной обработки данных) и Thumb-2.

ARM — самая популярная архитектура на мобильном рынке и прекрасно понимая, куда двигается рынок, в 2010 г. Microsoft выпустила Windows Phone для смартфонов, а в 2013-м — Windows RT для планшетов, помимо этого имеется отдельная версия ОС для Интернета вещей — Windows IoT. Рынок отнесся к мобильным Windows on ARM весьма неблагосклонно — недавно была приостановлена разработка версии для смартфонов, судьба Windows RT решилась ещё раньше — в 2015 г. все производственные партнеры Microsoft прекратили выпуск ARM-планшетов из-за небольшого спроса на них.

Причина заключалась в том, что планшеты с Windows RT могли запускать только те приложения, которые были написаны и скомпилированы для ARM при помощи WinRT API. Помощь WinRT API понадобилась, чтобы приспособить Windows для мобильных устройств, повысив заодно её безопасность и время автономной работы. Последнее Microsoft удалось, но сложность подкралась с неожиданной стороны — Windows RT не могла работать со стандартными программами для Windows: ни перекомпилированными, ни в режиме эмуляции. Решение Microsoft отказаться от запуска x86-софта на ARM было вынужденным: при всей своей энергоэкономичности ARM-чипы Tegra были малопроизводительными и не могли «переваривать» софт вне Windows Store, не говоря уже о том, чтобы обеспечить хорошую производительность для эмуляции.

Ситуация изменилась с выходом 64-разрядного чипа Snapdragon 835 (Qualcomm называет его «мобильной компьютерной платформой»), возможности которого гораздо шире ARM-процессоров первого поколения. Несмотря на то, что первые системы с Windows 10 S (наследница Windows RT) в продажу еще не поступили, известно, что их поставка предусматривает установку приложений из Windows Store, в который Microsoft разрешила разработчикам добавлять свои настольные приложения. Ещё одной возможностью станет бесплатный апгрейд Windows 10 S до полнофункциональной версии Windows 10 Pro, которую Microsoft разработала специально для ARM, подчеркивает Бренском.

Установив Windows 10 S on ARM, пользователь получает возможность инсталлировать x86-приложения в неограниченном количестве, но есть одна существенная деталь: несмотря на то, что и Snapdragon 835 Kryo, и версия Windows — 64-разрядные, ОС сможет работать только с 32-разрядными приложениями. Остается понять, каким образом и насколько качественно такой софт будет работать.

Windows на Windows on ARM

Внутреннее обустройство Windows — и ядро системы, и функции типа оболочки или Проводник — работают в нативном для ARM 64 коде. Подобным образом работают системные сервисы NTDLL (они требуются для общения приложений с ядром) и системные DLL для хранения, графики, сети и других драйверов устройств, которые также обращаются к ядру на аппаратном уровне минуя слой виртуализации. Универсальные приложения Windows (Universal Windows Platform, UWP), которые размещены в Windows Store, скомпилированы разработчиками в собственный ARM-код, тогда как x86-приложения работают в эмулированной среде поверх уровня абстракции WOW (Windows on Windows).

WOW уже не первый год работает в Windows. Первой вариацией этой системы стала субсистема, которая превращала 16-разрядные API в 32-разрядный эквивалент (процесс получил название «thunking»). Трансляция кода позволила запускать в единой виртуальной машине 16-разрядные приложения. В Windows 10 WOW применяется для запуска 32-разрядных приложений в 64-разрядной ОС. В задачи WOW входит не только переадресация DLL-вызовов, она проверяет и зеркалирует ключи реестра в зависимости от требуемой разрядности, регистрирует ODBC-соединения и предоставляет 32-разрядный интерпретатор CMD.EXE для вызовов командной строки. Все эти операции требуются для создания полноценной 32-разрядной среды и работы в ней 32-разрядных приложений.

Эмулированные приложения не используют виртуализацию наподобие виртуальных машин (которые эффективно работают с кодом в другой ОС, но при этом не различают аппаратного оборудование, на котором они работают), потому что запускаются на эмуляторе CPU. На компьютерах с 64-разрядными чипами AMD или Intel эмулятор встроен аппаратно, поэтому скорость его работы не уступает производительности процессоров x86. В системе ARM эмулятор запускается программно. Microsoft называет этот способ эмуляции Dynamic Binary Translator («динамический двоичный переводчик»), он ретранслирует блоки кода в код ARM 64 и кэширует его в памяти (или на диске), поэтому при повторном запуске одного и того же приложения его код не нужно повторно переводить. В задачу эмулятора входит распознавание различий, выходящих за рамки набора команд ARM, таких как упорядочение памяти и обработка исключений на RISC-процессорах типа ARM и процессорах Intel и AMD.

Связность логической системы ARM построена таким образом, что многопроцессорные системы могут использовать гораздо более дешевое оборудование для кеширования, но при этом для соблюдения последовательности операций памяти им необходимо создавать «барьеры». Они нужны для отслеживания потоков в многопоточной программе и коррекции правильного значения в переменных, когда те обновляются. Задача эмулятора состоит в следующем: ему приходится управлять барьерами, выдерживая баланс между количеством входных и выходных потоков. Если разгрузка потоков замедляется, то это, в свою очередь, приводит к тому, что потоку присваиваются неправильные значения от переменной и происходит сбой обработки кода.

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

Компиляция «на лету»

Особенность эмулятора Windows в том, что вместо интерпретируемой эмуляции в нём применяется гораздо более быстрая динамическая компиляция (dynamic translation) — технология увеличения производительности программных систем путём компиляции байт-кода в машинный код или в другой формат непосредственно во время работы программы. В отличие от статической, динамическая перекомпиляция вооружает эмулятор дополнительными сведениями о времени, которое требуется на перекомпилирование. Иногда для её обозначения употребляется термин JIT-эмуляция (Just-in-time compilation, компиляция «на лету»). Компиляция «на лету» по-прежнему медленнее, чем запуск собственного кода: впервые запущенная на эмуляторе программа будет работать в 50 раз медленнее, но после кэширования кода по скорости работы эмулированный софт практически ничем не будет уступать нативному. Для сравнения: интерпретируемая эмуляция одновременно может обрабатывать не больше одной команды, имитируя каждую инструкцию процессора по очереди.

Нужно заметить, что фактическая производительность того или иного приложения будет зависеть от того, какие ресурсы большую часть времени оно использует: CPU для вычислений, взаимодействует с системными файлами или с кодом ядра, загружает файлы, подключается к сети или требует графические ресурсы. В первом случае приложения будут работать медленнее из-за эмулирования, в остальных — скорость работы ограничивает лишь скорость железа. Очевидно, что приложения, которые генерируют код, довольно медлительные: эмулятору приходится транслировать и код приложения, и «рождаемый» им код.

«Многое также зависит от качества приложения. Проведя замер производительности некоторых приложений, мы обнаружили, что большинство эмулированного софта соответствует ожиданиям пользователей», — сказала генеральный менеджер по разработке Windows Эрин Чепл.

Библиотеки динамической компоновки стали динамичнее

Как уже говорилось, любые методы эмуляции приводят к системным задержкам. Один из способов повышения производительности WOW для 32-разрядных приложений в 64-разрядной Windows — это контрастно-интуитивный запуск копии системных DLL, которые поставляются с Windows в виде 32-разрядногоэмулированного кода. Исходный код Microsoft можно легко перекомпилировать в 64-разрядную версию, хотя приложения, которые общаются с этими DLL, используют 32-разрядные типы данных и 32-разрядные вызовы подпрограмм. В случае, если бы DLL-файлы были бы 64-разрядными, WOW пришлось бы симулировать для них каждый системный вызов, то есть переводить типы данных из 32-разрядных в 64-разрядные и наоборот, а также «сортировать» соглашения о вызовах в подстановку памяти.

Несмотря на то, что маршрутизацию между 32- и 64-разрядными вызовами можно автоматизировать, ретрансляция данных в x64-системах сильно замедляет производительность, тогда как эмулирование DLL, позволяющее многократное использование библиотек различными приложениями, отображается на производительности не столь пагубно.

Для эмуляции DLL на Windows on ARM Microsoft создала новый тип файлов — CHPE (Compiled Hybrid Portable Executable). Они компилируются в ARM 64-код с использованием того же исходного кода, что и нативные 64-разрядные версии DLL. Несмотря на то, что 32-разрядные x86-интерфейсы являются чужеродными в среде ARM 64, система автоматизирует сортировку соглашения о вызовах, поэтому библиотеки DLL работают с 32-разрядными типами данных, требуемых для загрузки x86-процессов. Член группы разработчиков ядра Windows Арун Кишан говорит, что такая комбинация ARM-кода и нативного кода 64-разрядных версий DLL для архитектуры x86 позволяет запускать x86-приложения в Windows Pro on ARM практически с той же скоростью, что и в среде Windows x86.

64-разрядность появится в Windows on ARM позже

Для Windows существует огромное количество программ. Несмотря на то, что многие из них работают на 32-разрядной архитектуре x86, количество 64-разрядного софта растет с каждым днем. Встаёт вопрос: как себя в режиме эмуляции на Windows on ARM поведут, к примеру, Photoshop и другие требовательные к ресурсам программы? И вот здесь кроется проблема, считает Бренском. Дело в том, что 64-разрядный софт в Windows on ARM работать не будет. Решение Microsoft не добавлять в ARM-систему такой софт вызвано труднопреодолимыми проблемами.

«Эмулирование x86 и без того сложная задача, а эмулирование x64 буквально удваивает объем инженерных работ. Кроме того, Windows поддерживает WOW только для 32-разрядных приложений. Возможно, в будущем мы добавим поддержку слоя 64-разрядности для WOW», — сказала Чепл. Нужно также учесть, что x64-процессоры обладают 16 регистрами общего назначения (небольшие хранилища, которые используются в процессоре для хранения текущей инструкции или данных), тогда как x86 имеют 8 регистров и это усложняет реализацию эмулирования для 64-разрядных программ.

Известно, что ядро Kryo 280 в Snapdragon 835 имеет 31 регистр общего назначения, к которым можно получить доступ либо в 32-, либо в 64-разрядном режиме (64-разрядная реализация более сложна для работы с кодом), но некоторая часть регистра зарезервирована под конкретные задачи и для действий эмулятора отводится несколько свободных регистров. Как правило, они завязаны на эмуляции и отвечают за её качество. Что на неё влияет? К примеру, если эмулятору требуется доступ к системной памяти для хранения и дальнейшей перезагрузки информации в аппаратные регистры, но он не получает доступа ко всему регистру, это немедленно влияет на скорость его работы: время обработки инструкции на такт процессора увеличивается от 20 до 50 раз.

Ранее говорилось, что запуск эмулируемого кода для 8 регистров, которые используют набор инструкций x86, проще, чем для архитектуры x64. Для того, чтобы включить для неё эмулирование, компилятору придется производить выделение на высокоуровневых языках, поскольку регистры защищены самой архитектурой системы. Задача усложняется тем, что 64-разрядный слой эмуляции придется разрабатывать с нуля, к тому же он не гарантирует бесшовную работу софта.

«Технически это возможно, но 64-разрядный слой — это компромисс между требуемыми пользователями ресурсами и пользой от применения 64-разрядных программ. Когда мы проанализировали данные телеметрии для самых часто используемых приложений Windows, мы обнаружили, что большинство из них — это x86, при этом некоторые приложения выпущены лишь в редакции x86. Большинство 64-разрядных приложений — это игры, которые находятся вне рамок целевой аудитории отдельно взятого девайса. Наконец, многие 64-разрядные приложения не могут работать в режиме эмуляции — они слишком требовательны к аппаратным ресурсам. В результате мы решили сосредоточить усилия наших инженеров на нативном ARM64 SDK, чтобы разработчики сами могли писать приложения для устройств», — сказала Чепл.

Таким образом, разработчикам, которые хотят, чтобы их x64-код заработал в Windows на ARM, нужно будет при помощи Desktop Bridge скомпилировать его для x86 и лишь тогда разместить в Windows Store. Нужно иметь в виду, что установщики программ также должны быть перекомпилированы в x86. Отметим, что Microsoft всегда подчеркивала значение 32-разрядных процессоров, тогда как многие дистрибутивы Linux отказались от их поддержки или собираются это сделать. В 2015 г. тогдашний глава программы Windows Insider Гейб Ол сказал, что есть «сотни миллионов 32-разрядных ПК», которые могут обновиться до Windows 10.

Как избежать эмуляции?

Эмуляция приложений — трудоёмкий процесс. Один из способов избежать её — это создание UWP-приложений, которые запускаются на ПК с Windows ARM изначально. Разработчики могут переработать существующие настольные приложения в UWP, воспользовавшись API WinRT и базовой версией (Core) .NET. Если они применяют такие функции, как WinForms, которым требуется полная версия .NET, тогда код программы придется перевести в x86 и запускать его в эмулированном виде.

Разработчики, которым требуются доступ к бόльшему количеству памяти и 64-разрядным виртуальным адресам, смогут использовать Windows SDK для Windows 10 ARM 64 и перекомпилировать свой код непосредственно в 64-разрядный код ARM, избегая потери производительности при эмуляции. Бренском советует им поэкспериментировать с кодом, написанном на языке C++, но при этом нужно учитывать, что для этого нужна определенная конфигурация, а готовые шаблоны проектов пока что отсутствуют. Отправлять экспериментальные программы в Windows Store Бренском не советует, поскольку на устройствах с Windows 10 S они работать не будут, но зато будут запускаться в Windows 10 Pro на ARM.

Относительно того, будет ли SDK включать поддержку таких функций, как WinForms, для которых требуется настольная версия .NET, Чепл сообщила, что Microsoft ещё не решила, какие версии .NET будут поддерживаться для ARM64 SDK. Она также поделилась информацией об эксперименте Microsoft с браузером Edge. Это 32-разрядное приложение, которое работает в ARM on Windows нативно, но может переключаться на ARM64. Чепл подтвердила, что Edge — одна из первых программ, для работы которой достаточно компонентов, имеющихся в Windows ARM64 SDK.

Пока что самыми популярными Windows-приложениями остаются Internet Explorer и Office, работающие на x86. Плагины и надстройки для них — также в подавляющем большинстве 32-разрядные, к тому же Office, хоть это одна из наиболее тяжелых программ, достаточно оптимизирована и не перегружает процессор. Из этого следует, что для x86 осталось место в будущем, и не стоит волноваться, что Microsoft хочет перевести весь софт в UWP. Более того, в отличие от Apple с её iPadPro, Microsoft даёт четкую установку — она не собирается отказываться от наследия x86 и ждёт его на Windows on ARM.

Одновременно компания посылает другой сигнал: несмотря на возрастающие производительность и возможности процессоров ARM, Microsoft не собирается соревноваться с Intel в «гонке разрядностей». Windows on ARM предназначена для комфортной работы на мобильных устройствах с упором на автономную работу от одного заряда батареи и интегрированную LTE-связь для быстрого Интернета.