0

I wanted to make use of hardware floating point support in my Android application which makes heavy use of the OpenCV library. However, when I set the gcc flags for hard-float (as described here and here) I get linker errors saying: XXX.o uses VFP register arguments, output does not. I then add linker flags -Xlinker --no-warn-mismatch which make these errors go away but the app crashes immediately on what seems to be the first interaction with the OpenCV library.

What exactly is going on? Am I compiling a hard-float version of my code and linking it with soft-float OpenCV?

Is there a version of OpenCV4Android with prebuilt binaries that are using hard-float architecture? If not, is it possible to compile such a version? How would one do that? Is there a smarter way to take advantage of hardware floating point support while using OpenCV?

Community
  • 1
  • 1
stav
  • 1,497
  • 2
  • 15
  • 40

1 Answers1

6

You don't need to build in hard-float mode in order to use the hardware floating point unit. As long as you build for the armeabi-v7a ABI, it will use the hardware floating point unit (VFPv3).

To clarify, the hard-float option (by adding the -mhard-float parameter to the compiler, or building for the armeabi-v7a-hard ABI) only changes the way that parameters are passed to functions. Internally, Android passes all float/double function parameters in integer registers. This makes sure that code built for armeabi (ARMv5 with no guarantee of a floating point unit, which needs to pass these parameters this way) still works when running on a modern device on an FPU. I.e., functions get all float parameters in integer registers and move them over to FPU registers to do all the calculations within functions.

When building with the hard-float option, such parameters are passed directly in FPU registers, but as your second link pointed out, this requires that all code that you call is built with the same option, and the JNI function entry points need to be marked properly with JNICALL.

So the actual benefit you get from hardfloat is only that you save a few instructions per function call (and as the answer in the first link points out, these are pretty cheap). Depending on the function structure of the libraries, this may amount to a completely insignificant change, or may be noticeable. Unfortunately I don't know the OpenCV internals well enough to guess how big potential speedup there would be, if any.

So to recap, yes, you're right that you're only building a hard-float version of your code but linking it to a soft-float ABI version of OpenCV. To make things work, you could also add __attribute__((pcs("aapcs"))) markers on all function calls into OpenCV, but that would pretty much throw away all the potential advantages, since all the heavy work (most probably) is done within the library, not in your calling code.

So to get the potential benefit of the hard-float ABI, you'd need to rebuild all of OpenCV with the -mhard-float parameter (exactly how to do that, I can't help you with though). But as long as it is built targeting the armeabi-v7a (with the -march=armv7-a -mfpu=vfpv3 parameters), it should already be using the hardware FPU, it just uses a backwards-compatible ABI. The overhead of the softfp ABI is a few orders of magnitude smaller than the overhead of a complete softfloat version (not built with -mfpu=vfpv3).

mstorsjo
  • 12,983
  • 2
  • 39
  • 62