С плавающей запятой или с фиксированной запятой для приложений Android NDK OpenGL?

Я пытаюсь решить, следует ли в первую очередь использовать плавающие или целочисленные значения для всех элементов, связанных с 3D, в моем приложении (по большей части C++). Я понимаю, что большинство ARM-устройств не имеют аппаратной поддержки с плавающей запятой, поэтому я полагаю, что любая тяжелая работа с поплавками будет заметно медленнее

Тем не менее, я планирую подготовить все данные по большей части (т. Е. Иметь вершинные буферы, где это применимо, и преобразовывать с использованием матриц, которые не сильно меняются), поэтому я просто запихиваю данные в горло OpenGL. Могу ли я предположить, что это идет более или менее прямо к графическому процессору и будет достаточно быстрым? (Между прочим, минимальное требование - OpenGL ES 2.0, так что предположительно исключает старые телефоны на основе 1.x).

Кроме того - каков штраф, когда я смешиваю и сопоставляю целые и плавающие числа? Предполагая, что вся моя геометрия - это просто предварительно созданные плавающие буферы, но я использую целые числа для матриц, поскольку для них требуются дорогостоящие операции, такие как умножение матриц, сколько гнева я буду здесь нести?

Кстати, я знаю, что я должен держать свои ожидания на низком уровне (звучит так, будто даже запрос поплавков на процессоре требует слишком многого), но есть ли что-нибудь отдаленно похожее на 128-битные регистры VMX?

(И я втайне надеюсь, что Фадден читает этот вопрос и имеет потрясающий ответ.)

2 ответа

Решение

Старые устройства Android, такие как G1 и MyTouch, имеют процессоры ARMv6 без поддержки плавающей запятой. Большинство новых устройств, таких как Droid, Nexus One и Incredible, используют процессоры ARMv7-A с аппаратным обеспечением FP. Если ваша игра действительно 3D-интенсивна, она может потребовать от 3D-реализации большего, чем старые устройства, так или иначе, поэтому вам нужно решить, какой уровень оборудования вы хотите поддерживать.

Если вы программируете исключительно на Java, ваше приложение будет использовать преимущества аппаратного обеспечения FP, если оно доступно. Если вы пишете собственный код с помощью NDK и выбираете архитектуру armv5te, вы вообще не получите аппаратную FP. Если вы выберете архитектуру armv7-a, вы это сделаете, но ваше приложение не будет доступно на устройствах до ARMv7-A.

OpenGL из Java теперь должен располагаться поверх "прямых" байтовых буферов, которые в настоящее время медленны для доступа из Java, но очень быстры с нативной стороны. (Однако я не очень разбираюсь в реализации GL, поэтому не могу предложить намного больше.)

Некоторые устройства дополнительно поддерживают расширение NEON "Advanced SIMD", которое предоставляет некоторые необычные функции, выходящие за рамки базовой поддержки VFP. Однако вы должны проверить это во время выполнения, если хотите использовать его (похоже, сейчас есть пример кода для этого - см. Страницу NDK для NDK r4b).

Более ранний ответ содержит некоторую информацию о флагах gcc, используемых NDK для "жесткого" fp.

В конечном счете, ответ "фиксированный или плавающий" зависит от того, на каком классе устройств должно работать ваше приложение. Конечно, проще написать код для armv7-a, но вы отрезаете себя от куска рынка.

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

Не только старые телефоны не поддерживают плавающую точку, но и новые, такие как HTC Wildfire.

Кроме того, если вы решите потребовать ARMv7, обратите внимание, что, например, Motorola Milestone (Droid для Европы) действительно имеет процессор ARMv7, но из-за того, что Android 2.1 был построен для этого устройства, устройство не будет использовать ваш armeabi. v7a libs (и может скрыть ваше приложение из Маркета).

Я лично работал над этим, обнаруживая поддержку ARMv7, используя новую библиотеку cpufeatures, поставляемую с NDK r4b, для загрузки некоторой библиотеки armeabi-v7a по требованию с помощью dlopen().

Другие вопросы по тегам