达夫设备
参考链接
代码实现
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这样就简单漂亮地解决了边界条件的问题。