【问题标题】:Does Duff's Device work in other languages?Duff's Device 是否支持其他语言?
【发布时间】:2009-05-03 17:23:46
【问题描述】:

多年前,在处理一个紧凑的图形 I/O 问题时,Tom Duff 展开了一个循环并创建了他的Duff's Device,如下所示:

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 语句。这种交错控制结构中的创造力可以在任何其他语言中使用吗?

【问题讨论】:

  • 什么是“旧式函数参数”?

标签: c


【解决方案1】:

您可以使用任何支持计算 GOTO 语句的语言(Fortran、一些 BASIC 等)

【讨论】:

  • 但是如果你不能动态计算 GOTO 也应该跳转的地址,它会变得非常麻烦,以至于它不再值得了。所以我认为在 PHP 这样的动态语言中这不是一个好主意......
【解决方案2】:

它在 C++ 中工作。

请注意,生成的代码取决于您的编译器。特别是,当我使用针对 ARM 架构的 GCC 编译 Duff 的设备时,生成的 ARM 汇编器在任何优化级别都不是最佳的(我认为 GCC 将它变成了一个跳转表)。

我最终只是把汇编程序的代码交给了。

【讨论】:

  • 是的,当编译器没有进行太多优化时(这是 Duff 提出它的时候),这很好。问题是,在每一步都有直通流程和“案例”标签,并且需要一个非常好的编译器才能确定它不需要刷新寄存器等。一个好的编译器可能是无论如何都能够展开天真的实现的循环。不过,这是一个很好的面试问题:)
【解决方案3】:

Duff 的设备本质上是一个计算得到的goto,它可以用许多其他语言来完成 - 汇编(当然)和 FORTRAN 是直接支持它们的一对。

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 你可以。清理案例不需要与循环相同。执行 n/8 次展开循环,最后执行 7 个条件步骤。考虑到它是针对大型阵列的,最后 7 个中的任何轻微低效率都会在噪音中消失。
    • Paul,如果清理用例与循环不同,那么我认为它不能再被称为 Duff 的设备了。 Duff 的设备不仅仅是循环展开。这是关于使用switch 语句跳转到展开循环的中间。
    【解决方案5】:

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

    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 产生非常相似的好处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 2015-02-08
      • 1970-01-01
      相关资源
      最近更新 更多