Этот пост относится к процессорам ARM и Цветным 3D-камерам Zivid.

Этим летом я стажировался инженером-программистом в Zivid. Для меня было бесценным опытом ежедневно работать в тесном контакте с такой умелой и преданной командой.

Лучше всего, пожалуй, уровень доверия всей команды ко мне — даже если я был «просто» стажером — всегда бросая мне вызов и мотивируя, а также возлагая на меня большую ответственность. Я сразу же почувствовал себя как дома инженером в команде!

Моей задачей этим летом был порт Zivid SDK на процессоры ARM. На сегодняшний день (дата публикации) Zivid SDK официально поддерживает компьютеры на базе x86_64. Однако в последнее время, с появлением устройств с мощными вычислительными возможностями, которые помещаются у нас на ладони, мы часто слышим один особый термин — ARM.

Процессор ARM, источник: https://www.arm.com/

Процессоры ARM с архитектурой вычислений с сокращенным набором команд (RISC) обычно требуют меньше транзисторов, чем процессоры с архитектурой вычислений со сложным набором команд (CISC). Например, процессоры на базе x86 от таких производителей, как Intel, AMD и др., встречаются в большинстве персональных компьютеров. Это приводит к улучшению стоимости, энергопотребления и рассеивания тепла. Эти характеристики желательны для легких портативных устройств с батарейным питанием, включая смартфоны и планшетные компьютеры, а также другие встраиваемые системы.

Несмотря на подавляющее преимущество ARM в мобильных и встраиваемых устройствах, в последнее время эта тенденция изменилась, и приток процессоров на базе ARM для ПК получил более положительный отклик. Например, уже в 2017 году Qualcomm и Microsoft анонсировали первые устройства Windows 10 с процессорами на базе ARM. Кроме того, в этом году Apple объявила о переходе на Macbooks на базе ARM. Следовательно, чтобы должным образом отреагировать и быть готовым к этому уже растущему спросу, у нас есть важный мотивационный фактор, объясняющий, почему мы должны (и переносим) наш SDK на ARM.

Как?

Первое ключевое слово для переноса Zivid SDK таким образом, чтобы не сильно замедлить конвейер тестирования, — это кросс-компиляция. Кросс-компиляция — это процесс компиляции кода для одной компьютерной системы (часто называемой целевой) в другой системе, называемой хостом.

На изображении ниже очень хорошо показан этот процесс:

Процесс кросс-компиляции

Не проще ли было бы просто выполнить компиляцию на компьютере с процессором ARM? Действительно, это упростило бы как сборку, так и тестирование кода. Однако, поскольку в распоряжении у нас было только встроенное системное (SOC) устройство — а-ля RockPro64 (довольно мощное по сравнению с другими SOC!) — сборка SDK была бы почти на порядок медленнее, чем в нормальная машина развития.

Кросс-компиляция, напротив, часто была такой же быстрой, как и собственная компиляция на машине разработки. Использование кросс-инструментальных цепочек, таких как Linaro toolchain, было спасением. Один вывод из этого процесса — будьте осторожны с преждевременной оптимизацией, особенно если вы нацелены на сборку для нескольких архитектур. Некоторые оптимизации часто зависят от архитектуры.

Одним из примеров является векторизация кода с помощью инструкций AVX и/или SIMD — для этого ARM использует свою архитектуру набора инструкций (ISA), называемую Arm NEON. Конечно, все зависит от варианта использования, но постарайтесь не забывать, что современные компиляторы очень умны и обычно генерируют очень эффективный код.

Второе ключевое слово для надежного и воспроизводимого переноса SDK — виртуализация сборок. Использование таких инструментов, как Docker, было необходимо мне для создания воспроизводимых сборок. Контейнеризация и виртуализация сборок и настроек дали дополнительное преимущество, поскольку они работали как документация о том, как, например, создавать определенные зависимости.

Это может быть очень удобно, если менеджер пакетов не используется — в этом случае зависимости нужно перекомпилировать под новую архитектуру. Худший случай неиспользования менеджера пакетов заключается в том, что вы окажетесь в большом беспорядке кросс-компиляции зависимостей, так как вам придется перекомпилировать зависимости каждой зависимости, а затем зависимости этих зависимостей и так далее…

Наконец, при условии, что код успешно кросс-компилируется, последним шагом будет его тестирование. Однако использование более слабых плат SoC ARM в качестве тестовых устройств в нашем конвейере тестирования не было привлекательным выбором. Основной причиной того, чтобы этого избежать, был объем вычислений, которые устройство SOC могло выполнять по сравнению с другими агентами тестирования, которые могли бы похвастаться мощными серверными процессорами.

Еще одной причиной, по которой следует избегать использования SOC в качестве агентов тестирования, могут быть потенциальные аппаратные проблемы, которые могут возникнуть на них, поскольку мы можем быстро сломать хранилище из-за частых операций чтения/записи на устройстве, поскольку оно использует SD-карту в качестве носителя данных. Наоборот, мы обнаружили, что эмуляция среды ARM с использованием QEMU работала достаточно хорошо. Естественно, он по-прежнему работал не так быстро, как исходный двоичный код x86_64, но избавил нас от использования новых и неизвестных машин в качестве агентов тестирования. Таким образом, сочетание использования функций эмуляции в QEMU с контейнеризацией в Docker привело к простому, воспроизводимому и независимому от платформы способу тестирования SDK.

Вывод

После того, как код SDK прошел все эти этапы, мы получаем мультиархитектурный порт SDK, который должным образом протестирован — без необходимости усложнять наш внутренний конвейер тестирования более слабыми встроенными устройствами!

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

Это то, что мы увидели, упростило нашу жизнь, например, позволив кросс-компилятору выполнять за нас общую оптимизацию, а Docker и QEMU виртуализировать и эмулировать для нас среду тестирования и сборки.

Наконец, я надеюсь, что смог передать веселые, разнообразные и сложные задачи, над которыми мне разрешили работать этим летом в Zivid.