7

I have an Android application which uses the NDK to execute a large amount of floating point math.

I just acquired a new Galaxy Nexus. To my surprise, my app runs MUCH slower than it should. I suspect this is because most devices are using hardware acceleration and the Galaxy Nexus is not. If I perform an operation which does not require floating point math, the Galaxy Nexus performs how I would expect.

Here are the CPU/GPU specs and sample timings for several devices. I've normalized the stats to take into account display resolution:

Droid
CPU: TI OMAP 3430 (ARM Cortex-A8 600 MHz underclocked to 550 MHz)
GPU: PowerVR SGX530
Instruction Set: ARMv7
Test Run: 1,980 pixels per second

Galaxy Nexus
CPU: TI OMAP 4460 (ARM Cortex-A9 dual-core 1.2 GHz)
GPU: PowerVR SGX540
Instruction Set: ARMv7
Test Run: 2,253 pixels per second

Droid Incredible
CPU: QSD8650 (Qualcomm Snapdragon 1 GHz)
GPU: Adreno 200
Instruction Set: ARMv7
Test Run: 4,571 pixels per second

I have this configuration in my Application.mk file:

APP_ABI := armeabi armeabi-v7a

I have not re-compiled my code with NDK-r7, but I don't understand why this would make such a dramatic difference. Any idea what is wrong?

dbyrne
  • 59,111
  • 13
  • 86
  • 103

3 Answers3

7

This StackOverflow question may be the cause of the poor performance on your Galaxy Nexus: Galaxy Nexus - wrong CPU ABI being selected during install time.

That seems to be a bug. I've tested it also by creating a small project using native code and indeed Galaxy Nexus chooses the wrong library (armeabi instead of armeabi-v7a).

I've reported this bug at http://code.google.com/p/android/issues/detail?id=25321 , with the sample project attached on the bug. Please star it to bring attention to Android engineers.

Community
  • 1
  • 1
Randy Sugianto 'Yuku'
  • 71,383
  • 57
  • 178
  • 228
5

You could try to use APP_ABI := armeabi-v7a to force use of the v7a instructions only.
I could imagine that the new CPU is not detected as supporting v7a instructions and that thus the no-FPU code is used at runtime as a fallback.

JimmyB
  • 12,101
  • 2
  • 28
  • 44
  • This worked. However, this is pretty depressing, because now I have no way of putting one app on the market which all phones support. I'd hate to post two different applications just because of this. – dbyrne Dec 26 '11 at 17:12
  • Personally I've been looking into renderscript direction for compatibility. And not only for supporting different kinds of CPUs but also for easy to implement multiprocessor support and possible GPU utilization. – harism Dec 28 '11 at 22:48
  • 1
    You can include different versions of a native library within the same app; remember that the libs are loaded _at runtime_ through your Java code. Maybe its possible to do the FPU detection inside your app, e.g. like [described here](http://stackoverflow.com/questions/8161184/detecting-fpu-presence-on-android), and then load the corresponding native lib. – JimmyB Dec 30 '11 at 11:05
0

I think the problem is that there are 2 cores in the processor. Thus, you have 600 Mhz for one core. So if your math method uses only one thread this can be an answer. Although, I do not understand why it is 2 times slower (comparable time can be explained).

Yury
  • 20,618
  • 7
  • 58
  • 86
  • I have seen a phone marketed as "2 GHz" when in fact it was a dual-core 1 GHz phone, but I assure you the Galaxy Nexus has two 1.2 GHz processors. – dbyrne Dec 23 '11 at 16:37
  • You bring up a good point that I should multithread my calculation code. Especially since it would be trivial to parallelize it. – dbyrne Dec 23 '11 at 16:50