跳至主要內容

达夫设备

马龙伟...大约 3 分钟笔记C/C++

参考链接

C语音冷门知识点:达夫机!switch还可以这么玩open in new window

代码实现

void send( int * to, int * 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 );
    }
}

什么是达夫设备

百度百科说法如下:

相关信息

在计算机科学领域,达夫设备(英文:Duff's device)是串行复制(serial copy)的一种优化实现,通过汇编语言编程时一常用方法,实现展开循环,进而提高执行效率。这一方法据信为当时供职于卢卡斯影业的汤姆·达夫于1983年11月发明,并可能是迄今为止利用C语言switch语句特性所作的最巧妙的实现。

达夫设备是一个加速循环语句的C编码技巧。其 基本思想 是--减少循环测试的执行次数。

实现机制

  • 在达夫解决这个问题的时候,当时的C语言对switch语句的规范是比较松的,在switch控制语句内,条件标号(case)可以出现在任意子语句之前,充作其前缀。

  • 此外若未加入break语句,则在switch语句在根据条件判定,跳转到对应的标号,并在开始执行后,控制流会一直执行到switch嵌套语句的末尾。

  • 利用这种特性,这段代码可以从连续地址中将count个数据复制到存储器中,映射输出寄存器中。

  • 另一方面,C语言本身也对跳转到循环内部提供了支持,因而此处的switch/case语句便可跳转到循环内部。

执行流程

  • 程序执行到了switch的时候,就会根据n的值,直接跳转到 case n那里,再当它执行到while那里时,就会判断循环条件。若为真,则while循环开始,程序跳转到do那里开始执行循环;为假,则退出循环,即程序中止。(这个swicth语句就再也没有用了)

  • 我们再看以下代码,这里 count 个字节从 from 指向的数组复制到 to 指向的内存地址,是个内存映射的输出寄存器。它把 swtich 语句和复制 8 个字节的循环交织在一起, 从而解决了剩余字节的处理问题 (当 count % 8 != 0)。

    void send( int * to, int * 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 );
        }
    }
    
  • switch内的表达式计算被8除的余数。执行开始于while循环内的哪个位置由这个余数决定,直到最终循环退出(没有break)。Duff's Device这样就简单漂亮地解决了边界条件的问题。

你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.5