接下来就要讲的就是NEON这个东西了.
一开始见到它还觉得它是一个可有可无的技术,后来看了很多的文章以后发现这个才是优化的突破口.
1.什么是SIMD其实这个术语我很久以前就已经听过了,可以一直只有表面的理解,不就是单指令多数据流吗.难道这个还能比MIMD还要牛逼吗,一直觉得这是一种可有可无的技术,就算就在今天我还是觉得这样的技术就是过渡性的技术.可是今天看了一篇文章以后才发现它都有用之处.
通常我们进行多媒体处理的时候,很多的数据都是16位或者8位的,如果这些程序运行在32位的机器上,那么计算机有一部分的计算单元是没有工作的.所以这是一种浪费.为了更好的使用那些被浪费的资源.SIMD就应运而生了.SIMD这种技术就是使用一条指令,但对多个相同类型和尺寸的数据进行并行处理.就像我们现实生活中的好几个人都在做同一件事情那样,这样就可以将速度提升很多倍.
2.什么是NEONARMv7体系结构介绍了增强性SIMD的扩展,它通过定义大量了在64位和128位的寄存器指令用来扩展了SIMD的概念.
据文档上了解NEON就是将增强性SIMD的扩展使用在ARM处理器上的实现.也就是说NEON是指用一种特定的方式去实现的过程.现在ARM Cortex-A8的系列是具有着NEON.具有NEON技术的处理器都会配备了32个64位的寄存器和16个128位的寄存器,它们分别被标识为(D0-D31),(Q0-Q15)
NEON的指令集只是ARM和THUMB指令集中的子集,ARM和THUMB要管理所有程序流和同步的问题.NEON指令通常执行的就是:
内存的访问
在NEON寄存器和传统寄存器之间的数据拷贝
数据类型的转化
数据的处理
3.关于NEON的编程模式如何才能去优化NEON的代码呢??
这就是怎么样去使自己编写的代码能整合进NEON的技术,这样编译器就可以在编译的过程中尽可能的使用NEON的处理方式.
要使用NEON,那就使用NEON本身支持的指令效果最好了,那么NEON本身提供了什么样的指令呢??
就像上面所说那样,本身NEON指令提供的功能也很有限,主要在于数据的装载和存储,以及数据的处理.这应该是NEON指令的核心能力了.NEON的指令都是以V字母开头的.
VADD.I16 q0,q1,q2
这就是一个NEON的指令了,很明显的特点就是V开头,I主要用来表明是一个整型,16表示一个16位的整型,q0,q1,q2都是128位的寄存器(q打头的寄存器都是128位的).其实这个指令的意思就是让q1,q2中装载8个16位的数据,然后执行加法操作,最后放到q0中去.这么一个指令就完成了8次加法运算,也就是性能的提升.
像上面的指令,NEON还有很多.比如还提供比如RGB三个元素,分别取到3个不同的寄存器中,每一个寄存器中的元素要不都是R要不都是G要不都是B,这样一来就可以进行并行运算了.
既然知道了这些指令,那么使用到程序中去的话有几种手段呢??
C语言级别的C语言级别的优化当然是对高级语言这个阶段来说的,对于NEON来说,这个级别的优化不是指那些很通用的优化手段,虽然那些能达到优化的作用,但是没有充分的利用NEON这的技术,所以很多时候你会发现,网上很多人说这个板子很厉害很厉害,可是你在上面开发的程序就是很慢很慢,这也就说明了你没有充分的利用其中的硬件资源.
C语言的优化可以分为两个手段:
内联函数
内联函数有可能会被误会成我们通常想的那样,主要是这个单词我翻译不正确(intrinsics).这样的函数可以被C和C++的程序所调用.看上去和别的函数没有很多的区别,最多也就名字比较古怪.但是其实当这个代码在被编译器编译的时候,它会被转化为有序的低级指令.这些指令就是NEON的指令了.所以这样就办到了在高级语言层次使用低级语言了.主要是很简单的可以使用.最为主要的就是程序员不用去接触汇编了,可以减小优化的难度.当然我可以说这样的优化效率没有使用汇编的来的高.
对于上面的这种技术其实就是ARM公司本身给你做好了一些函数,你就直接调用这些函数,这些函数在编译的时候就可以直接转化成NEON的汇编指令.为了支持这些内联的函数所以必须要包含头文件arm_neon.h.
#include <arm_neon.h>
uint32x4_t double_elements(uint32x4_t input)
{
return(vaddq_u32(input, input));
}
像vaddq_u32这样的函数,gcc还提供很多很多,如果想知道更多可以查看gcc_neon.
当然使用了NEON技术以后必须还要通过在编译的时候加入-mfpu=neon才能起到效果的.整个编译的命令就是arm-none-linux-gnueabi-gcc -mfpu=neon intrinsic.c
汇编级别的
这个级别的优化是比较难的,但是也是最为有效的.通过对NEON指令的掌握然后对程序中消耗最大的那个部分进行汇编级别的改造,这样会有很大的区别.我昨天看了一篇文章上讲了,c级别的改造只提高性能1.5倍,但是汇编级别的就是7.5倍,从中可以看出之间的差距了吧.
使用库
ARM公司好像本身对NEON的技术做成了一个库(OPENMAX),里面都是ARM公司作了NEON作的优化程序.所以可以使用这些库函数来完成一些功能.可以在ARM