Question

I'm trying to compile a third party library (FFTW) for Android which is running on an ARM device. The library includes a benchmark tool which I want to run on my device. Following Google's instructions (https://developer.android.com/tools/sdk/ndk/index.html) on how to configure for hard float with NDK r9d I'm using the following flags:

NDK_ROOT="/opt/android/ndk"
TOOLCHAIN="$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/"

export SYS_ROOT="$NDK_ROOT/platforms/android-18/arch-arm"
export CC="$TOOLCHAIN/arm-linux-androideabi-gcc --sysroot=$SYS_ROOT"
export LD="$TOOLCHAIN/arm-linux-androideabi-ld"
export AR="$TOOLCHAIN/arm-linux-androideabi-ar"
export NM="$TOOLCHAIN/arm-linux-androideabi-nm"
export RANLIB="$TOOLCHAIN/arm-linux-androideabi-ranlib"
export STRIP="$TOOLCHAIN/arm-linux-androideabi-strip"

export CFLAGS="-mfpu=vfpv3-d16 -mhard-float -D_NDK_MATH_NO_SOFTFP=1"
export LDFLAGS="-Wl,-lm_hard -Wl,--no-warn-mismatch"


./configure \
--host=arm-linux-androideabi \
--disable-fortran \
--disable-shared \
--enable-static \
--enable-threads \
--with-combined-threads \
--enable-single \
--prefix=$INSTALL_DIR

With this configuration the benchmark is performing extremely poor. To me it looks like the library is compiled with softfloat or a soft float libm is linked.

How can I configure the library to use hard float? Am I missing an essential step?

I know that the FPU on my device works because I have a second device running ArchLinux on which the library and benchmark perform as expected, i.e. 600% faster than on Android.

Was it helpful?

Solution 2

I was able to resolve the issue. There were three points missing.

  1. Firstly I was missing compiler optimization. Turning on -O2 significantly improved performance. So the CFLAGS are

    CFLAGS="-O2 -mfpu=vfpv3-d16 -mhard-float -D_NDK_MATH_NO_SOFTFP=1"
    
  2. The second point is library and platform speficic. This post (Application hang after call nested function with Android NDK) delivers the answer. In short add

    --with-slow-timer 
    
  3. As @andrewsieh said it is necessary to edit configure so that libm is not always linked before libm_hard.a

OTHER TIPS

In order to link hard-float version of math functions in libm_hard.a, you need to put -lm_hard after all objects files but before -lm, which is Android's libc.so compiled in soft-float. LDFLAGS="-Wl,-lm_hard" doesn't work in FFTW because it's put before all object files. LIBS="-lm_hard" may work, but configure sets LIBS="-lm $LIBS" at the end, which puts -lm in front of -lm_hard. You can remove that line in configure to workaround, although a better fix is to allow customization of system math lib, or filter out -lm in ltmain.sh if -lm_hard is present for $host arm-*linux-android.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top