自动矢量化编译优化技术(Automatic Vectorization)

自动矢量化技术,是编译器代码优化技术的一种,即在不改变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的汇编格式大不相同,因而移植非常困难。

 

期待自动矢量优化的进一步发展,关注中。。。

 

参考文献:

(1)I've Fallen In Love With the Vectoriser

(2)Auto-vectorization in GCC

(3)Auto-Vectorization and C++

 

你可能感兴趣的:(优化,汇编,Microsoft,compiler,编译器,vectorization)