如何在交叉编译适用于Android的FFTW时启用硬浮动

时间:2014-05-15 08:48:37

标签: android android-ndk cross-compiling

我正在尝试为在ARM设备上运行的Android编译第三方库(FFTW)。该库包含一个基准工具,我想在我的设备上运行。按照Google的说明(https://developer.android.com/tools/sdk/ndk/index.html)了解如何使用NDK r9d配置硬浮动我使用以下标记:

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

使用此配置,基准测试表现极差。对我来说,看起来这个库是用softfloat编译的,或者软浮动libm是链接的。

如何配置库以使用硬浮点?我错过了一个重要的步骤吗?

我知道我的设备上的FPU有效,因为我有第二台运行ArchLinux的设备,其中库和基准测试按预期运行,比在Android上快600%。

2 个答案:

答案 0 :(得分:1)

为了在libm_hard.a中链接hard-float版本的数学函数,你需要在所有对象文件之后但-lm_hard之前放置-lm,这是在软件中编译的Android的libc.so浮动。 LDFLAGS="-Wl,-lm_hard"在FFTW中不起作用,因为它放在所有目标文件之前。 LIBS="-lm_hard"可能有效,但最后会配置集LIBS="-lm $LIBS",这会将-lm放在-lm_hard之前。您可以在configure中删除该行以解决方法,但更好的解决方法是允许自定义系统数学库,或者如果-lm存在-lm_hard,则过滤掉ltmain.sh中的$host arm-*linux-android

答案 1 :(得分:0)

我能够解决这个问题。缺少三个点。

  1. 首先,我缺少编译器优化。打开-O2显着改善了性能。所以CFLAGS

    CFLAGS="-O2 -mfpu=vfpv3-d16 -mhard-float -D_NDK_MATH_NO_SOFTFP=1"
    
  2. 第二点是图书馆和平台的特点。这篇文章(Application hang after call nested function with Android NDK)提供了答案。简而言之,添加

    --with-slow-timer 
    
  3. 正如@andrewsieh所说,有必要编辑 configure ,以便在libm_hard.a

  4. 之前并不总是链接libm