x86 vs ARM: переписать нельзя портировать

21 Янв 2016

Особенности разработки кроссплатформенных приложений для Android и х86

Сосуществование архитектур ARM и x86 в сегменте портативных мобильных устройств ставит разработчиков перед необходимостью выработки подходов к созданию кроссплатформенных приложений. Пока решения еще далеки от идеала, а кроссплатформенностью иногда называют снижение трудозатрат на адаптацию написанного кода. С появлением серверных ARM-платформ вопрос расстановки запятых для предложения в заголовке статьи волнует уже не только авторов игрушек. Прежде чем детально анализировать наборы инструкций и побитно сравнивать регистры контроллеров прерываний и межпроцессорного взаимодействия GIC/APIC, обратимся к документу Android on Everything и рассмотрим ряд частных аспектов.

Выравнивание данных в памяти

Выравниванием (Alignment) называется такое размещение объектов в памяти, при котором базовый адрес объекта кратен его размеру в байтах. Например, для 128-битного векторного операнда, определенного в архитектуре Intel SSE, выровненный адрес будет кратен 16, то есть адрес должен содержать нули в четырех младших двоичных разрядах.

Преимущество выравнивания состоит в повышении производительности. Несколько упрощая, можно сказать, что если объект выровнен, его границы совпадают с границами блоков данных, передаваемых из памяти за один цикл шины. Иначе может потребоваться два цикла шины, если объект распределен по двум блокам. Есть и недостаток: неэкономный расход памяти.

Классические инструкции x86 допускают работу с памятью без выравнивания (режим Packed), разумеется ценой некоторого снижения производительности. В функциональных расширениях SSE/AVX есть инструкции, для которых выравнивание обязательно.

Для ARM правила более строгие: 64-битные операнды должны быть выровнены.

Сравнение основных характеристик процессорных архитектур ARM и x86
Рис.1. Сравнение основных характеристик процессорных архитектур

Пример выравнивания операндов: для ARM, поле Padding обеспечивает кратность адреса переменной mVar2 ее размеру, а именно 8 байтам; для x86, адрес переменной mVar2 может быть не кратен 8, поэтому поле Padding не требуется
Рис.2. Пример выравнивания операндов: для ARM, поле Padding обеспечивает кратность адреса переменной mVar2 ее размеру, а именно 8 байтам; для x86, адрес переменной mVar2 может быть не кратен 8, поэтому поле Padding не требуется

Векторные вычисления

Незатейливая простота сравнительной таблицы Рис.3, за прямым сопоставлением численных параметров, скрывает тот факт, что функциональные расширения SSE и NEON являются принципиально разными архитектурами. Их детальное сравнение выходит за рамки нашего обзора.

Сравнительные характеристики наборов инструкций NEON и SSE
Рис.3. Сравнительные характеристики наборов инструкций NEON и SSE. Возможность адресации 16 SSE-регистров в 64-битном режиме, а также технологии AVX256/512 не упомянуты, видимо в силу того, что речь о процессорах для ультра-компактных устройств. Также, сделаем поправку на дату создания таблицы

Fat Binaries

Понятие Fat Binaries упомянутое в документе или, в автоматическом буквальном переводе «упитанные двоичные файлы», связано с реализацией кроссплатформенного приложения методом интеграции в него нескольких выполняемых модулей, каждый из которых предназначен для одной из поддерживаемых архитектур. В нашем примере такими модулями являются Linux Shared Objects. Очевидно, если пойти по другому пути и написать выполняемый код в системе команд некоторой виртуальной машины, то достаточно будет и одного экземпляра, но производительность в этом случае будет существенно ниже.

Процесс сборки кроссплатформенного приложения: необходимость поддержки нескольких ABI (Application Binary Interface), усложняет исходный код и приводит к наличию нескольких модулей в файле Android Package
Рис.4. Процесс сборки кроссплатформенного приложения: необходимость поддержки нескольких ABI (Application Binary Interface), усложняет исходный код и приводит к наличию нескольких модулей в файле Android Package (APK)

Резюме

Рекомендации плана простой и быстрой адаптации нативного кода x86 для ARM и обратно, местами напоминающие давно забытые «Призывы ЦК КПСС к советскому народу» вызывают закономерный скепсис у специалистов, понимающих, что ARM и x86 это две принципиально разные архитектуры. Очевидно, потребуется кропотливая работа, которая не сводится к корректировке правил выравнивания операндов и другим частным аспектам, если конечно качественная оптимизация производительности и эффективность использования процессорных ресурсов важны для вашего приложения. Тем не менее, эмблемы Google и Intel на первой странице документа позволяют предположить, что задача решается с приемлемым качеством...

Литература

[1] Android on Everything. Smooth Development of Cross-platform Native Android Games // Ian Ni-Lewis. Google. Orion Granatir. Intel Corporation.

[2] Android 6.0 Compatibility Definition // Last updated: October 16th, 2015

[3] Конвенции вызова: Microsoft vs Linux

Теги: