DSP

Neon 使用小结

2019-07-13 17:42发布

测试平台: OMAP3430 SDP。 注意点:默认TI 给的uImage或者config 都是不支持neon的,需要重新make menuconfig,来enable这个功能。 参考:http://tiexpressdsp.com/wiki/index.php?title=FAQ_OMAP35x_Linux_PSP#How_to_enable_the_NEON_coprocessor.3F   TOOLCHAIN: arm-2007q3。 这个是GCC 官方支持neon的第一款。     编译选项:(针对内联的,汇编的话后面几个可以不用,担放着也没有问题) CFLAGS = -s -save-temps -static -Wall -O3 -march=armv7-a -mtune=cortex-a8 -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=neon -ftree-vectorize -fomit-frame-pointer -ffast-math       Neon参考文献: 从ARM 官方上下载DUI0204IC_rvct_assembler_guide  / DUI0348BC_rvct_comp_ref_guide, 两个都有中文版本,看起来很方便。配合最新的arm_architecture_reference_manual,应该足够了。   优化方法 两种方法我都尝试了下:  1: 使用内联 http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html  2:直接使用汇编   在简单函数的时候,两种差异不大;担担随着功能负责,使用内联会导致寄存器分配不够,反复压/出栈,而性能降低。同时使用内联也没有办法调整好流水线,(感觉NEON的大多数指令包括ADD等,都不是单周期的的,具体几个周期,我没有查到)。如果用汇编调整好的话,一般能够提高30+%   感觉:  和一般SIMD 指令差不多,支持16个128bit的寄存器。可以看成 16×8bit;8×16bit; 4×32bit...。指令功能还是很全的,甚至什么max,倒数都能够支持。也支持直接读/写chuncky数据BRG,YUYV啥的,简单的IF/ELSE也能支持。   用内联写的话很方便,函数合适的话,估计半天一个很轻松,一般优化个2 -3倍没问题。如果不够的话,就用ASM精细搞下。     不足: 我遇到一个优化失败的地方。程序是个梯度计算,本来是很合适的。担输入数据和目的数据都是YUYV,而我们只要处理Y好了。结果NEON必须同时读入YUYV(再展开成planar),这样多读/写了一倍数据,结果把性能托慢了。 这个模块计算太简单,ARM本身已经很快了,读写数据已经是瓶颈了,NEON的多读写数据就把优化的效果给干掉了。如果NEON能够支持“跳”着读/写,就好了,^_^。