最近在纠结于大数据的checksum的计算,算法如下:
1 unsigned long cs_cal(const unsigned char *buff, unsigned long size) 2 { 3 unsigned long cs; 4 5 cs = 0; 6 while (size--) 7 cs += buff[size]; 8 9 return cs; 10 }
当文件大于4G后这种计算的龟速就很明显了,在网上看到大牛说MMX指令对于数据计算相当不俗,于是改成下面代码(bug:不对齐部分没有处理,这部分消耗很小,对于效率影响不大):
1 unsigned long cs_cal(const unsigned char *buff, unsigned long size) 2 { 3 unsigned long cs; 4 unsigned long cs_2[2]; 5 unsigned long cnt; 6 7 cnt = size / 2; 8 __asm { 9 mov eax, 0 10 movd mm2, eax 11 mov ecx, cnt 12 mov esi, buff 13 cnt_label: 14 mov al, byte ptr[esi] 15 movd mm0, eax 16 inc esi 17 18 mov al, byte ptr[esi] 19 movd mm1, eax 20 inc esi 21 22 punpckldq mm0, mm1 23 24 paddd mm2, mm0 25 26 dec ecx 27 jnz cnt_label 28 29 movq qword ptr [cs_2], mm2 30 31 32 emms 33 } 34 cs = cs_2[0] + cs_2[1]; 35 #endif 36 return cs; 37 }
测试1G的内存数据发现速度近快了2倍,MMX的威力果然不是吹的.