向量化并不是新的技术:本书的作者在1998年使用Cray Y-MP EL“lite”时从Cray Y-MP supercomputer line看到过。
例子:
这段代码从A和B中取出元素,相乘,并把结果保存到C。
如果每个元素为32位int型,那么可以从A中加载4个元素到128bits XMM寄存器,B加载到另一个XMM寄存器,通过执行PMULID(Multiply Packed Signed Dword Integers and Store Low Result)和PMULHW(Multiply Packed Signed Integers and Store High Result),一次可以得到4个64位结果。
循环次数从1024变成1024/4,当然更快。
函数如下:
{
ar3[i]=ar1[i]+ar2[i];
};
Intel C++ 11.1.051 win32下编译:
icl intel.cpp /QaxSSE2 /Faintel.asm /Ox
可以得到(IDA中):
SSE2相关指令是:
MOVDQU (Move Unaligned Double Quadword)—仅仅从内存加载16个字节到XMM寄存器。
MOVDQA (Move Aligned Double Quadword)—把源存储器内容值送入目的寄存器,当有m128时,必须对齐内存16字节.
否则,ar2处的值将用MOVDQU加载到XMM0,它不需要对齐指针,代码如下:
movdqu xmm1, xmmword ptr [ebx+edi*4] ; ar1+i*4
movdqu xmm0, xmmword ptr [esi+edi*4] ; ar2+i*4 is not 16-byte aligned, so load it to xmm0
其他情况,将没有SSE2代码被执行。
22.1.2 GCC
gcc用-O3 选项同时打开SSE2支持: -msse2.
可以得到(GCC 4.4.1):
几乎一样,但没有Intel的细致。