Look over the print_cpu_features function found in the Lab11_Task1 project. This function helps identify the type of CPU being used and what features are available. These functions can help guard code optimized for different CPU features or to load certain libraries depending on CPU features.
Build two NDK toolchains, one for ARM and one for x86.
$NDKROOT/build/tools/make-standalone-toolchain.sh --platform=android-<API_VERSION> --arch=<ARCHITECTURE> --install-dir=<DIRECTORY>
Use these toolchains to compile the timing library. You must set the CROSS_COMPILE variable for make to use the new toolchains. The CROSS_COMPILE variable must contain the path to the toolchain and the common root of the tools. For example:
make CROSS_COMPILE=/home/student/ndk_x86_toolchain/bin/i686-linux-android-
Compile the library for both x86 and ARM and give them a different name. Add the libraries to your project. In Application.mk make sure to select only x86, armeabi and armeabi-v7a.
Then, in Android.mk, add the library module to the compilation:
include $(CLEAR_VARS) ifeq ($(TARGET_ARCH_ABI),x86) ARCH_SRC_FILES := libtiming_x86.a endif ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) ARCH_SRC_FILES := libtiming_arm.a endif ifeq ($(TARGET_ARCH_ABI),armeabi) ARCH_SRC_FILES := libtiming_arm.a endif LOCAL_MODULE := timing LOCAL_SRC_FILES := $(ARCH_SRC_FILES) include $(PREBUILT_STATIC_LIBRARY)
Test that the project compiles correctly. Run the program and check how much time it takes for the loop in timing_test to run. Check the header of the library for API details.
Add the timing library to the Lab11_Task3 project. Compile the project with -O0 flags (LOCAL_CFLAGS) and check how much time it takes to run the grayscale function. Then compile the project with -O2 and check again. Try the -msse, -msse2 and -msse3 and see if there is any noticeable difference. On ARM, see if compiling with NEON support makes any difference. To add NEON support, append to the file name in the Android.mk file (not the filename itself) the .neon extension.
Since the architecture and features are not known at compile time, an usual way to choose optimized code is to dynamically load libraries. Compile the files in the optimized_libs folder using the android toolchain. Add these libraries to one of the project in the libs folder. Use dlopen to load the library, once the 'unoptimized' one (libprint_no.so) and then the optimized one (libprint_o.so). Add the header print.h header to your project and call the optimized_print function after calling dlopen.