转自:http://blog.csdn.net/lifesider/article/details/6571192
自动矢量化技术,是编译器代码优化技术的一种,即在不改变C/C++源代码的情况下,自动编译产生使用单指令多数据(Single Instruction Multiple Data,SIMD)指令集的二进制码,包括MMX,SSE,SSE2,SSE3,SSSE3,SSE4,AVX,而不是程序员手动编写汇编层次的优化代码。
举例如下:
- float a[N], b[N], c[N];
- for(int i=0; i<N; ++i)
- c[i] = a[i] + b[i];
上述代码中,逐项相加,并且a,b,c三个数据间是相互独立的,因而编译器可以对其进行矢量化优化,比如对于SSE指令集,XMM 128位寄存器,一次可以执行4个浮点运算,即
- float a[N], b[N], c[N];
- int i;
- for(i=0; i<N-4; i+=4)
- {
- __asm
- {
- movups xmm0, a[i];
- addps xmm0, b[i];
- movups c[i], xmm0;
- }
- }
- for(; i<N; ++i)
- c[i] = a[i] + b[i];
当N较大时,如大于100,矢量优化后的执行速度提升是明显的。
同样,对于其它类型的数值运算,如整形和双精度浮点数,可用类似的指令如mulps,mulpd,addpd,subps,subpd等进行优化。
当循环内部有依赖关系导致无法优化时,编译器将产生通用汇编代码。
目前矢量优化技术在当前流行的编译器上已经得到支持,如Intel C++ Compiler,GCC,预计Microsoft Visual Studio 2010也支持,并且从Microsoft Visual Studio 2008的编译结果中发现,对于浮点操作,已经使用SSE指令movss,cvttps2dq等代替x87指令集。
当然,当循环体嵌套层次更深,循环体内实现代码较多时,编译器判断循环体内是否能进行矢量优化将会比较耗时。同时,虽然支持SSE2指令集的处理器已经非常普遍,但不保证会有使用较老机器的用户,因而在进行矢量化编译优化时,也可选择产生多份代码,如同时编译出通用汇编代码和SIMD优化汇编代码,运行时使用CPUID指令检测当前CPU支持的指令集进行跳转选择执行。
自动矢量编译优化技术是一个巨大的进步,并且具有更好的可移植性。这是由于编写可移植的C/C++代码更容易,而对于汇编底层的开发者而言,由于Intel汇编和AT&T的汇编格式大不相同,因而移植非常困难。
期待自动矢量优化的进一步发展,关注中。。。