Как обнаружить crc32 на aarch64 - PullRequest
0 голосов
/ 29 декабря 2018

Возможно ли для пользовательской программы на aarch64 определить, доступны ли инструкции crc32?Я обнаружил ссылки на поддержку ядра для такого обнаружения, подразумевая, что регистры с информацией о том, какие инструкции будут работать в пользовательском режиме, недоступны в пользовательском режиме (!).

Является ли этодело?Или есть портативный способ определить, доступны ли инструкции crc32?

Примечание. Под терминами «пользовательская программа» и «переносимый» я подразумеваю подход, который не требует привилегированных инструкций и не зависит от операционной системы.звонки или файлы (например, / proc / cpuinfo).Сам код должен уметь обнаруживать наличие инструкций и использовать их, если они есть, или использовать альтернативу, если их нет.Например, у процессоров Intel есть инструкция cpuid для этой цели.

Обновление:

Выискивая описания архитектуры ARM, я обнаружил регистр уровня пользователя, PMCR_EL0, который предоставляет 8-битный код разработчика и 8-битный код ID для процессора.Возможно, если бы я мог найти список этих кодов, я мог бы быть ближе к тому, что я ищу.

Обновление 2 :

Однако, когда я пытаюсьпрочитав этот регистр, я получаю недопустимую инструкциюТак что даже для регистров EL0 требуется привилегированный доступ?

Ответы [ 3 ]

0 голосов
/ 02 января 2019

это может быть недоступно напрямую;но ARM предоставит спецификации для каждого процессора - поэтому есть шанс создать диаграмму, которую можно использовать для поиска функций ЦП по названию модели./proc/cpuinfo является специфичным для Linux;Windows эквивалент будет WMI;OSX не работает на ARM (насколько я знаю).если это не будет гипервизор типа 1, который полностью обходит операционную систему, должен существовать код, специфичный для ОС (и пользователь также может отключить VT).

0 голосов
/ 16 января 2019

Насколько я знаю.

То, как я реализовал это в Zlib Chromium, использовало доступные функциональные возможности ОС: https://cs.chromium.org/chromium/src/third_party/zlib/arm_features.c?l=29

Также важно упомянуть, чтоИнструкции crc32 в ARMv8 являются частью крипто-расширений, которые являются необязательными для ARMv8 и обязательными для ARMv8-1.Это также означает, что обнаружение функции времени выполнения необходимо, для получения более подробной информации, пожалуйста, проверьте: https://cs.chromium.org/chromium/src/third_party/zlib/BUILD.gn?l=64

Я бы избегал чтения напрямую из / proc / cpuinfo, так как это может быть недоступно в некоторых контекстах (так как также зависит отна аромате Android это может быть ложный минус).

В Chromium zlib будет запускаться как в привилегированном контексте (т. Е. В части сетевого кода в основном процессе браузера), так и в изолированном контексте (т. Е. В части RendererProcess на вкладке).В RendererProcess чтение из / proc / cpuinfo должно завершиться неудачей.

Подход кувалдой - установить обработчик сигнала и выполнить инструкцию со встроенным asm, что приведет к ошибке, если инструкция недоступна (иможет быть захвачен обработчиком).Однако не рекомендуется.

Вышеупомянутый пример (https://github.com/torvalds/linux/blob/master/Documentation/arm64/cpu-feature-registers.txt) работал на 1 плате ARM, которую я тестировал (MachiatoBin), но не удался на 2 других (rock64 и nanopi m4).

Подход, реализованный в Chromium, работает на всех платах (также как и на нескольких мобильных телефонах, которые я тестировал).

Еще одна деталь о getauxval: правильный флаг изменится, если он работает на 32-битной или 64-битной версии.будет HWCAP_CRC32, в то время как в 32 битах это будет HWCAP2_CRC32.

О подходе sledgehammer : Сигналы подвержены гонкам, плюс вы все равно будете полагаться на использование специфичных для ОС API (т.е.установите обработчик сигнала).

Наконец, в зависимости от контекста, если данная задача падает (даже если она задана и изолирована от контекста выполнения), она вызовет красные флаги.

Этоэто точка (то есть обнаружение функций), где жизнь на x86 намного проще.

При этом может быть приемлемым компромиссом полагаться на функции ОС.отправлял связанный код в Chromium с момента выпуска M66 (текущая стабильная версия - M72), впервые полученная почти год назад без каких-либо плохих отчетов.

Одним из соображений на Android было то, что внутренне NDK может реализовать android_getCpuFeatures (), используяdlopen () / dlsym (), который может добавить около 500us к 1000us при первом запуске, поэтому мы кешируем результат обнаружения функции процессора.

Еще одним соображением для многопоточных приложений (таких как Chromium) былонужен барьер для потока (то есть pthread_once_t), чтобы избежать состояния гонки при выполнении определения характеристик процессора.

0 голосов
/ 29 декабря 2018

Обновление: оригинальный ответ не ответил на вопрос, так как его автор хотел, чтобы какая-то универсальная часть кода работала на EL0, способном определить, присутствует ли функция CRC32 или нет, без каких-либо требований к операционной системе или среде с «голым железом».used.

Насколько я понимаю, такой код должен был бы получить доступ к ID_AA64ISAR0_EL1, и поскольку код, выполняющийся с EL0, не может получить к нему доступ, в любом случае потребуется переключение на более привилегированный уровень исключения.

Точно так же для захвата недопустимой инструкции с использованием «переносимого» раздела кода потребуется доступ к регистру VBAR_ELx, чего нельзя добиться с помощью программы, работающей на EL0, которая не будет зависеть от какой-либо базовой операционной системы / привилегированного монитора.

Поэтому мой ответ на вопрос "Так ли это?"будет: Да, это так, что переносимый / универсальный раздел кода, работающий на EL0, не может определить, доступна ли функция CRC32.

Это, как говорится, пример кода, представленный в документации ссылка в вопросе работает нормально на Expressobin под управлением aarch64 linux 4.14.80 и должна быть предпочтительнее использования getauxval () по причинам, объясненным в документации ядра.

...