4

我正在使用本机代码在 Android 中进行一些图像压缩。由于各种原因,我不能使用预建库。

我使用 android-ndk-profiler 分析了我的代码,发现瓶颈是——令人惊讶的是——浮点运算!这是配置文件输出:

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 架构核心做了更多的研究,除非我遗漏了什么,否则它没有硬件浮点支持。那么我可以在这里做些什么来加快速度呢?固定点?我知道这通常是用整数完成的,但我不确定如何转换我的代码来做到这一点。有没有我可以设置的编译器标志,所以它会这样做?欢迎提出其他建议。

4

2 回答 2

8

当然,你可以只用整数算术做任何事情(毕竟这正是你的程序现在正在做的事情),但它是否可以更快地完成,取决于你到底想要做什么。

浮点数是一种通用解决方案,您可以在大多数情况下应用并忘记它,但是您的问题确实需要从难以置信的小到难以置信的大并且具有 52 位尾数精度的数字,这有点罕见。假设您的计算是关于具有双精度浮点数的图形,您可以从远小于亚原子尺度到远大于宇宙的大小......真的需要那个范围吗?提供的精度当然取决于 FP 的刻度,但您真正需要的精度是多少?

您的“内循环”中使用的数字是什么?在不知道的情况下,很难说计算是否可以提高很多。几乎可以肯定它可以变得更快(FP 是一种通用的盲目解决方案),但您可能希望获得的增益程度会有很大差异。我不知道具体的实现,但我希望它相当有效(对于一般情况)。

您应该瞄准更高的逻辑优化级别。

对于基于说 DCT 或小波变换的图像(去)压缩,我认为确实不需要浮点运算:您可以只考虑您的数字的确切比例并使用整数运算。此外,由于产生近似结果的能力,您可能还具有额外的自由度。

于 2012-06-17T06:26:09.530 回答
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 并得到不好的结果是可能的,而且很容易,只是让它们更快。很容易写出糟糕的浮点代码。无论您使用固定还是浮动,您都需要跟踪数字的范围,并从该控制中移动点以将整数数学保持在尾数内的核心。这意味着要有效地使用浮点数,您应该考虑整数数学在做什么。一个非常常见的错误是认为乘法会破坏您的精度,而实际上加法和减法对您的伤害最大。

于 2012-06-18T07:15:28.940 回答