提高代码的运行效率 (3)


【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

 

4、编译的时候,我们习惯于在头文件中包含很多其他的文件,不管他们对我们是有用还是没有用,殊不知这样会带来很大的麻烦。一方面,它会在我们修改头文件的时候造成麻烦,另外一方面会给我们的编译带来很多的麻烦。我们知道,一般的工程项目都有少则上百个,多则上千个上万个文件。如果在每一个文件上面节约一点编译的时间,那么久整个项目或者工程来说也是相当可观的。

 

5、尽量不要使用乘除,多使用移位操作

#define LOOP_MAX_NUMBER 10000000L
int data[LOOP_MAX_NUMBER] = {0, 1};
void test10()
{
    int m = GetTickCount();
    int inner = 0;
    int value = 10;
    for(inner = 0; inner < LOOP_MAX_NUMBER; inner ++)
    {
        data[inner] = inner / 16 + inner / 32 * 8;
    }  
  
    printf("%d\n", GetTickCount() - m);

    m = GetTickCount();
    for(inner = 0; inner < LOOP_MAX_NUMBER; inner ++)
    {
        data[inner] = inner >> 4 + (inner >> 5) << 3;
    }
    printf("%d\n", GetTickCount() - m);
}

 

6、所谓SIMD指令就是指用一条指令,完成多个字节数据的操作,我们不妨看一个范例。

 

static void mmx_memcopy(void* dst, void* src, int len)
{
     __asm
     {
         mov ecx, [len]
         test ecx, ecx
         mov eax, 63
         mov esi, [src]
         jle over

         and eax, ecx
         mov edi, [dst]
         sub ecx, eax
        jz  mov_remain

mov64bytes:
       add esi, 64
       add edi, 64
       sub ecx, 64
       movq mm0, [esi -64]
       movq mm1, [esi -64 + 8]
       movq [edi - 64], mm0
       movq [edi - 64 + 8], mm1
       movq mm2, [esi -64 + 16]
       movq mm3, [esi -64 + 24]
       movq [edi - 64 + 16], mm2
       movq [edi - 64 + 24], mm3
       movq mm4, [esi -64 + 32]
       movq mm5, [esi -64 + 40]
      movq [edi - 64 + 32], mm4
      movq [edi - 64 + 40], mm5
      movq mm6, [esi -64 + 48]
      movq mm7, [esi -64 + 56]
      movq [edi - 64 + 48], mm6
      movq [edi - 64 + 56], mm7
      ja mov64bytes

mov_remain:
      test eax, eax
      mov ecx, eax
      je over

      shr eax, 3
      cmp eax, 7
      je mov_remain56

      cmp eax, 6
      je mov_remain48

      cmp eax, 5
      je mov_remain40

      cmp eax, 4
      je mov_remain32

      cmp eax, 3
      je mov_remain24

      cmp eax, 2
      je mov_remain16

      cmp eax, 1
      je mov_remain8

      jmp mov_remain7

mov_remain56:
     movq mm0, [esi]
     sub ecx,8
     add esi,8
     movq [edi],mm0
     add edi, 8

mov_remain48:
     movq mm0, [esi]
     sub ecx,8
     add esi,8
     movq [edi],mm0
     add edi, 8

mov_remain40:
     movq mm0, [esi]
     sub ecx,8
     add esi,8
     movq [edi],mm0
     add edi, 8

mov_remain32:
     movq mm0, [esi]
     sub ecx,8
     add esi,8
     movq [edi],mm0
     add edi, 8

mov_remain24:
     movq mm0, [esi]
     sub ecx,8
     add esi,8
     movq [edi],mm0
     add edi, 8

mov_remain16:
     movq mm0, [esi]
     sub ecx,8
     add esi,8
     movq [edi],mm0
     add edi, 8

mov_remain8:
     sub ecx, 8
     movq mm0, [esi]
     movq [edi], mm0

     je over

     add esi, 8
     add edi, 8

mov_remain7:
     rep movsb

over:
     emms
 }
}

     这是一个简单的内存拷贝代码,它和我们通常意义上的C拷贝代码还是有很大的不同的,因为是8个字节一起复制的,所以它使用了mm0~mm7共8个寄存器,对于剩下来的余数字节又是分别进行处理的,所以一旦拷贝的数据量很大,效果还是相当明显的。

【注: 此处代码摘自 《C/C++多媒体开发案例实践》Page 40 ~ Page 42,版权属于原作者,转载请注意。】

 

(待续)

posted on 2011-09-21 11:12  四-儿  阅读(203)  评论(0编辑  收藏  举报

导航