Я пытаюсь создать библиотеку для процессора Cortex A9 ARM (более OMAP4), и я немного замешана в отношении того, когда\когда использовать NEON vs VFP в контексте с плавающей запятой операций и SIMD. Следует отметить, что я знаю разницу между двумя аппаратными сопроцессорами (как также указано здесь, на SO), у меня просто есть недоразумение относительно их правильного использования.
В связи с этим я использую следующие флаговые компиляции:
GCC
-O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
-O3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp
ARMCC
--cpu=Cortex-A9 --apcs=/softfp
--cpu=Cortex-A9 --fpu=VFPv3 --apcs=/softfp
Я прочитал документацию по ARM, много wiki (как этот), форумы и сообщения в блогах, и все, кажется, согласитесь, что использование NEON лучше, чем использование VFP или, по крайней мере, смешение NEON (например, использование instrinsics для реализации некоторых альго в SIMD), а VFP - не такая хорошая идея; Я не уверен на 100%, если это применимо в контексте всей библиотеки приложений\или только к определенным местам (функциям) в коде.
Поэтому я использую neon как FPU для своего приложения, так как я также хочу использовать встроенные функции. В результате у меня немного неприятности, и я смутился о том, как лучше использовать эти функции (NEON vs VFP) на Cortex A9, только углубляется дальше, а не проясняется. У меня есть код, который выполняет бенчмаркинг для моего приложения и использует некоторые пользовательские таймерные классы в которых вычисления основаны на двойной точности с плавающей запятой. Использование NEON в качестве FPU дает совершенно неулокальные результаты (попытка распечатать эти значения приводит к печати в основном inf и NaN, тот же код работает без сбоев при построении для x86). Поэтому я изменил свои вычисления на использование одинарной точности с плавающей запятой, поскольку документировано, что NEON не обрабатывает плавающую точку с двойной точностью. Мои тесты по-прежнему не дают правильных результатов (и, что хуже всего, теперь это больше не работает на x86, я думаю, это из-за потери точности, но я не уверен). Поэтому я почти полностью потерял: с одной стороны, я хочу использовать NEON для возможностей SIMD и использовать его, поскольку FPU не дает правильных результатов, с другой стороны, смешивание его с VFP не кажется очень хорошей идеей. Любые советы в этой области будут очень благодарны!
Я нашел в статье в вышеупомянутой wiki сводку того, что должно быть сделано для оптимизации с плавающей запятой в контексте NEON:
"
- Использовать только одинарные точки с плавающей запятой
- Используйте NEON intrinsics/ASM, когда вы найдете функцию FP с узким местом. Вы можете сделать лучше, чем компилятор.
- Свернуть условные ветки
- Включить режим RunFast
Для softfp:
- Встроенный код с плавающей запятой (если только его очень большой)
- Передавайте аргументы FP через указатели вместо значения и выполняйте целочисленные операции между вызовами функций.
"
Я не могу сильно использовать для float ABI, поскольку я не могу связываться с библиотеками, которые у меня есть. Большинство рекомендаций имеют смысл для меня (за исключением "режима runfast", который я не понимаю точно, что должно было делать, и того факта, что в этот момент я мог бы сделать лучше, чем компилятор), но я продолжаю получать противоречивые результаты и Я ничего не знаю прямо сейчас.
Может ли кто-нибудь пролить свет на то, как правильно использовать плавающую точку и NEON для Cortex A9/A8 и какие флаговые компиляции использовать?