Linux内存分页导致memcpy慢,SIMD指令优化memcpy函数

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字节对

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值