YOLO:NNPACK评估 - zhonglong/TPV GitHub Wiki
NNPACK用于神经网络加速,基于多核并行计算和SIMD(单指令多数据流)。以优化Darknet为例,darknet-nnpack运行在树莓派3上,按README.md的介绍,先在树莓派下载源代码验证,再考虑移植到Android平台。
Darknet with NNPACK https://github.com/digitalbrain79/darknet-nnpack NNPACK for Darknet https://github.com/digitalbrain79/NNPACK-darknet
依赖库包括:pthreadpool,FXdiv,FP16和psimd,下载到NNPACK-darknet的deps目录下。除pthreadpool外,其余三个库只使用头文件。
pthread-based thread pool for C/C++ https://github.com/Maratyszcza/pthreadpool C99/C++ header-only library for division via fixed-point multiplication by inverse https://github.com/Maratyszcza/FXdiv Conversion to/from half-precision floating point formats https://github.com/Maratyszcza/FP16 Portable 128-bit SIMD intrinsics https://github.com/Maratyszcza/psimd
根据darknet-nnpack/Makefile可知,编译带NNPACK的Darknet依赖nnpack和pthreadpool两个库,这两个库都是通过编译NNPACK-darknet源码(含deps)得到的。
ifeq ($(NNPACK), 1) COMMON+= -DNNPACK CFLAGS+= -DNNPACK LDFLAGS+= -lnnpack -lpthreadpool endif
最初的设想是采用树莓派上编译好的库,但树莓派上编译生成的是.a文件(静态库),无法直接用于Android。
根据NNPACK-darknet的描述,和NNPACK-darknet/jni/Android.mk可知,NNPACK-darknet支持Android交叉编译。
Cross-compilation for Android - Download and setup Android NDK - Add ndk-build to PATH variable - Navigate to NNPACK directory and setup dependencies (confu setup) - Build NNPACK with ndk-build build system.
因为本机没有配置ndk-build,所以还是决定以源码方式导入。
-
将darknet-nnpack的include和src目录同步到DarknetDemoInAndroid/app/src/main/cpp/darknet下;
-
根据NNPACK-darknet/jni/Android.mk,将NNPACK-darknet,pthreadpool,FXdiv,FP16和psimd五个工程的源代码拷贝到DarknetDemoInAndroid/app/src/main/cpp/nnpack下;
-
根据根据NNPACK-darknet/jni/Android.mk,修改DarknetDemoInAndroid/app/CMakeLists.txt,将NNPACK源代码加入编译;
-
修改build.gradle和CMakeLists.txt,启用NNPACK和clang编译器,并禁用OpenMP;
导入NNPACK后,性能有明显提升,在X588识别时间从4秒左右减少到1秒左右,在锤子M1L识别时间从1.2秒以内减少到0.6秒以内。
NNPACK主要采用两种方式来提升性能: 一是多线程,采用pthread线程库; 二是算法优化,卷积层(convolutional_layer)正向传播(forward)改用nnp_convolution_inference函数; 其余如NEON指令向量化,在darknet-nnpack并未直接使用。
因NNPACK也是BLAS加速库,不再使用Darknet的gemm函数,无法与功能相同的OpenBLAS同时使用。
NDK Crash有两种定位方式:addr2line和ndk-stack,Android Studio下采用ndk-trace会比较简单。 先将NDK目录加入环境变量,再切换到工程目录,以TpvYolo为例,输入:
adb logcat | ndk-stack -sym TpvYolo\app\build\intermediates\cmake\release\obj\arm64-v8a\libdarknetlib.so
请参考:
Android studio下使用ndk-stack定位crash https://blog.csdn.net/a568478312/article/details/78182422