Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76159
  • 博文数量: 17
  • 博客积分: 789
  • 博客等级: 军士长
  • 技术积分: 145
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-01 17:46
文章分类
文章存档

2010年(17)

我的朋友

分类: C/C++

2010-06-24 20:26:57

Duff's device 达夫设备
      在计算机科学中达夫设备是对于连续拷贝内容的一种精巧改进,这个方法使用了在汇编中被广泛使用的循环展开的方法。
      我们首先看一段代码:

do { /* count > 0 assumed */
    *to = *from++; /* Note that the ''to'' pointer is NOT incremented */
} while (--count > 0);


    这断代码将from指向的内存地址的count个字节拷贝到to指向的地址中。由于在实际意义中,to指向一个输出寄存器,所以to指向的地址不用被改变。

    达夫注意到,可以通过将switch结构和循环结构交替来循环展开该程序,完整的程序如下:


#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int data[] = {1,2,3,4,5,6,7,8,9,10};

int main( int argc, char* argv[]) {
    
    int count = 10;
    register n = (count + 7) / 8; /* count > 0 assumed */
    int* to,*from;

    to = (int*)malloc(sizeof(int));
    from = data;
    printf("from = %p data = %p\n",from,data);
    switch (count % 8)
    {
    case 0: do { *to = *from++; printf("%d\n",*to);
    case 7: *to = *from++; printf("%d\n",*to);
    case 6: *to = *from++; printf("%d\n",*to);
    case 5: *to = *from++; printf("%d\n",*to);
    case 4: *to = *from++; printf("%d\n",*to);
    case 3: *to = *from++; printf("%d\n",*to);
    case 2: *to = *from++; printf("%d\n",*to);
    case 1: *to = *from++; printf("%d\n",*to);
          } while (--n > 0);
    }
}


    可以看到,这段代码switch和do while 循环交替了。可以看出来,实际上switch语句和循环语句并没有本质的区别。正是利用这个性质,达夫发现了一种巧妙的优化。
    之所以上述程序比普通的程序效率要高的原因是因为在汇编代码中,对于case值连续的switch分支,往往被实现为一个跳转表的形式,所以可以更高效。

参考的网址:
维基百科Duff's Device
阅读(1218) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~