2012-06-17 3 views
4

Я делаю сжатие изображения в Android с помощью собственного кода. По разным причинам я не могу использовать предварительно созданную библиотеку.Ускорение операций с плавающей запятой (Android ARMv6)

Я профилировал свой код с помощью андроида-ndk-профайлера и обнаружил, что узкое место - удивительно - операции с плавающей запятой! Вот вывод профиля:

Flat profile: 

Each sample counts as 0.01 seconds. 
    % cumulative self    self  total   
time seconds seconds calls ms/call ms/call name  
40.37  0.44  0.44        __addsf3 
11.93  0.57  0.13  7200  0.02  0.03 EncodeBlock 
    6.42  0.64  0.07 535001  0.00  0.00 BitsOut 
    6.42  0.71  0.07        __aeabi_fdiv 
    6.42  0.78  0.07        __gnu_mcount_nc 
    5.50  0.84  0.06        __aeabi_fmul 
    5.50  0.90  0.06        __floatdisf 
    ... 

Я гугл __addsf3 и, видимо, это работа программного обеспечения с плавающей точкой. Тьфу. Я сделал больше исследований по ядру архитектуры ARMv6, и, если я не пропустил что-то, он не поддерживает аппаратную поддержку с плавающей запятой. Так что я могу сделать здесь, чтобы ускорить это? Фиксированная точка? Я знаю, что это обычно делается с целыми числами, но я не уверен, как конвертировать мой код для этого. Есть ли флаг компилятора, который я мог бы установить, чтобы он это сделал? Другие предложения приветствуются.

ответ

8

Конечно, вы можете делать что-либо только с целочисленной арифметикой (ведь именно это именно то, что вы делаете сейчас), но если это можно сделать быстрее или не совсем зависит от того, что именно вы пытаетесь сделать.

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

Ваши данные используются в вашей "внутренней петле"? Не зная, что трудно сказать, можно ли сделать вычисление быстрее или не много. Почти наверняка это можно сделать быстрее (FP - это общее слепое решение), но степень выигрыша, на которую вы можете надеяться, сильно варьируется. Я не знаю конкретной реализации, но я ожидаю, что она будет достаточно эффективной (для общего случая).

Вы должны стремиться к более высокому логическому уровню оптимизации.

Для сжатия изображения (де), основанного на использовании DCT или вейвлет-преобразования. Я думаю, что на самом деле нет необходимости в арифметике с плавающей запятой: вы можете просто рассмотреть точные масштабы вашего номера и использовать целочисленную арифметику. Более того, вы также можете получить дополнительную степень свободы из-за способности производить приблизительные результаты.

2

Смотреть отличный ответ 6502 в первом ...

Большинство процессоров не имеет fpus, потому что они не нужны. И когда они по какой-то причине пытаются соответствовать IEEE754, что в равной степени необязательно, случаи, которые нуждаются в любом из них, встречаются довольно редко. Fpu - это просто целочисленный alu с некоторыми вещами вокруг него, чтобы отслеживать плавающие точки, все из которых вы можете сделать сами.

Как? Давайте подумаем о десятинах и долларах, о которых мы можем думать о $ 110,50 и добавив $ 0,07 и получив $ 110,57, или вы могли бы просто сделать все в гроши, 11050 + 7 = 11057, а затем, когда вы распечатаете его для пользователя, разместите точку в нужном месте. Это все, что делает fpu, и это все, что вам нужно сделать. эта ссылка может дать или не рассказать об этом http://www.divms.uiowa.edu/~jones/bcd/divide.html

Не используйте все процессоры ARMv6 таким образом, чтобы не классифицировать ARM. Некоторые ядра имеют возможность для FPU, или вы можете добавить их самостоятельно после покупки из ARM и т. Д. ARM11 - это ARMv6 с опцией для fpu, например.

Кроме того, только потому, что вы можете отслеживать десятичную точку самостоятельно, если есть жесткий fpu, возможно, чтобы она была быстрее, чем сама, в фиксированной точке. Точно так же возможно и легко не знать, как использовать fpu и получить плохие результаты, а просто получить их быстрее. Очень легко писать плохой код с плавающей запятой. Независимо от того, используете ли вы фиксированный или плавающий, вам нужно отслеживать диапазон ваших чисел и от этого элемента управления, где вы перемещаете точку вокруг, чтобы сохранить целочисленную математику в ядре в мантиссе. Это означает, что эффективно использовать плавающие точки, вы должны думать о том, что делает целочисленная математика. Одна из распространенных ошибок заключается в том, чтобы думать о том, что умножение испортит вашу точность, когда это на самом деле добавление и вычитание, которые могут причинить вам боль.

Смежные вопросы