SIMD(Single Istruction Multiple Data), 即单条指令处理多个数据。是在通用处理器上对程序性能进行优化的利器,尤其在进行大量数据进行相同操作时,更能凸显优势,在Intel X86家族中主要有MMX/SSE/SSE2等指令集构成。memcpy函数即从源地址向目的地址复制一块数据,利用SIMD对其优化有很好的效果。如普通汇编指令 mov eax,ebx一次能复制两个字节的数据,而MMX指令 movq mm1,mm2可以复制8个字节的数据,mm1,mm2分别为MMX指令寄存器为64位,而SSE指令movdqa xmm1,xmm2一次复制16个字节!
函数原型:
void *memcpy( void *dest, const void *src, size_t count );
由于内存分页机制,在操作系统内核地址是否按16字节或是8字节等的对齐对数据存取操作性能有很大影响,未对齐就对数据复制操作很浪费时间,如SSE指令movdqa是16字节对齐的移动操作,movdqu是未对齐时的移动操作,虽然两者功能相同,但movdqa指令周期要远远小于movdqu的指令周期所以在优化前要先检查目的地址和源地址地址是否能够对齐,对齐以后SSE指令注意是“能够”对齐,可能分配时还没有对齐,但经过先从源地址向目的地址复制几个字节以后就对齐,比如两个首地址源地址为 253 ,目的地址 1021 ,虽然都没有按照16字节对齐,但通过先分别复制 253,254,255地址的数据v到1021,1022,1023地址处以后,剩下的地址就是16字节对齐的,因此在复制前应当先检查地址是不是能够以16字节对齐,不行的话再检查是不是可以按8字节对齐,如果8字节还不能对齐,再 检查可不可以4字节对齐,如果都不行 的话只能按照最普通的汇编语言处理了。因为16字节对齐可以用SSE指令集,8字节对齐可以用MMX指令集,4字节对齐可以用rep movsd指令,都不可以的话就只能 movsb 了,:)。
检测是否对齐就通过比较16进制地址末几位是否相等,如检测16字节是否对齐就检测末四位,8字节是否对齐就检测末三位等等。
汇编语言 函数流程如下:
将地址移入到相应寄存器:
mov edi,[esp + 8 + 4];dst
mov esi,[esp + 8 + 8];src
mov ecx,[esp + 8 + 12];count
计算count包含多少个16字节,保存在ecx中,判断如果count<=1就不再判断,直接按照普通复制处理:
mov eax,ecx
and eax,15 ; save the 16 unaligned bits
shr ecx,04H ; save num of double qua_dword
cmp ecx,1 ;if so few , move it as Byte
jg nextt
jmp normal_copy2
如果count>1 再检测能否16字节对