2009-05-03 69 views
6

许多年前,而在紧张的图形工作的I/O问题,汤姆·达夫展开的循环,并创造了他Duff's Device如下:(注意这个使用旧式函数参数 - 这是不是一个错误)Duff的设备是否可以用其他语言工作?

dsend(to, from, count) 
char *to, *from; 
int count; 
{ 
    int n = (count + 7)/8; 
    switch (count % 8) { 
    case 0: do { *to = *from++; 
    case 7:  *to = *from++; 
    case 6:  *to = *from++; 
    case 5:  *to = *from++; 
    case 4:  *to = *from++; 
    case 3:  *to = *from++; 
    case 2:  *to = *from++; 
    case 1:  *to = *from++; 
      } while (--n > 0); 
    } 
} 

这种编码直接在C语言的汇编和编码思想中出现,并且依赖于C的case语句。隔行扫描控制结构中的这种创造力可以用其他语言工作吗?

+0

什么是“旧式功能参数”? – 2017-04-08 08:52:54

回答

4

你能做到在支持计算GOTO语句的任何语言(Fortran语言,一些基础知识等)

+0

但如果你不能动态计算GOTO应该跳过的地址,它会变得如此繁琐以至于它不再是真的值得。所以我不认为在PHP等动态语言中这会是一个好主意...... – 2011-12-27 23:08:35

3

它在C++中起作用。

请注意,虽然生成的代码取决于您的编译器。尤其是,当我编译使用GCC的ARM架构的Duff器件时,得到的ARM汇编器在任何优化级别都不是最优的(我认为GCC将它转换为跳转表)。

我结束了刚刚编写的汇编程序。

+3

是的,当编译器没有优化的时候(当达夫提出它的时候)是好的。问题在于,在每一步都有drop-through流和'case'标签,并且需要一个非常好的编译器来确定它不需要刷新寄存器等。并且一个好的编译器可能会无论如何能够展开天真实现的循环。 不过,做一个很好的面试问题:) – 2009-05-03 18:19:54

2

达夫设备本质上是一个计算goto可以在许多其他语言来完成 - 组件(当然)而FORTRAN则是直接支持他们的一对。

2

我在JavaScript中非常成功地使用它来加速大型数组处理。我希望我可以在C#中使用它。

+2

你可以。清理案例不需要与循环相同。做展开循环n/8次,然后在最后7个条件步骤。鉴于它适用于大型阵列,因此在噪声中会丢失最近7次的任何次要低效率。 – 2009-05-03 18:16:28

0

即使不能用这种方式,你可能仍然有两个循环:

dsend(to, from, count) 
char *to, *from; 
int count; 
{ 
    int n; 
    for(n=0; n!=count/8; n+=8){ 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
    } 
    for(; n!=count; n++) 
    { 
     *to = *from++; 
    } 
} 

当然,这将是较小的count有点慢,但它是有点更具可读性,有些更便携的跨语言,很产生与大型count类似的好处。

相关问题