什么是达夫设备(Duff's Device)

摘要:
当Duff向C开发人员和全世界发布这一技术时,他注意到C的swtick语法,特别是“fall”行为,一直存在争议,“`代码”在争论中形成了一些争论,但我不确定是赞成还是反对“函数包含一个switch语句,其case语句同时位于while循环中。Duff‘s Device简单而漂亮地解决了边界条件问题。Duff’s Device在这里是一个新颖而富有创意的解决方案。Duff的Device对效率的负面影响可能来自代码膨胀和特殊结构。事实上,Duff设备使用switch语句来控制l他们进入循环的地方。

在看《你必须知道的496个C语言问题》一书中,提到"达夫设备"这个东西,主要是下面的代码:

register n = (count + 7) / 8; /\* count > 0 assumed \*/

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);

}

这是个很棒的迂回循环展开法, 由 Tom Duff 在 Lucasfilm 时所设计。它的 ``传统" 形态, 是用来复制多个字节。

这里 count 个字节从 from 指向的数组复制到 to 指向的内存地址 (这是个内存映射的输出寄存器, 这也是为什么它没有被增加)。它把 swtich 语句和复制 8 个字节的循环交织在一起, 从而解决了剩余字节的处理问题 (当 count 不是 8 的倍数时)。相信不相信, 象这样的把 case 标志放在嵌套在 swtich 语句内的模块中是合法的。当他公布这个技巧给 C 的开发者和世界时, Duff 注意到 C 的 swtich 语法, 特别是 ``跌落" 行为, 一直是被争议的, 而 ``这段代码在争论中形成了某种论据, 但我不清楚是赞成还是反对"

函数包含一个switch语句,它的case语句同时位于一个while循环体内(有一个case语句在外面)。switch内的表达式计算被八除的余数。执行开始于while循环内的哪个位置由这个余数决定,最终循环退出,(没有break)。Duff's Device这样就简单漂亮地解决了边界条件的问题。顺便提一下,为什么"case 0"标记在循环外面呢?这样不是打破了对称的美观吗?这样做的唯一理由是为了处理空序列。当余数为零,"case 0"内就需要执行一个多余的测试来判断空序列的可能性。总之,这是个很酷的算法。

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

如果在一个for循环中,其中操作执行得如果足够快(比如说,一个赋值)——那么测试循环条件占用了循环所用时间的很大部分。循环应该被部分解开,这样数个操作一次完成,测试操作也做的较少。其实,是通过switch语句将要进行的连续循环操作的次数进行了预判(根据擦case语句的位置)然后依次执行,而不必每次都去进行测试条件。

在这里Duff's Device是个新颖的,有创造力的解决方案。这里有一个使用该模型的一个实例:快速拷贝和填充。

Duff's Device对效率的负面影响可能来自于代码膨胀(一些处理器更善于处理紧凑的循环而不是大的循环)和特别的结构。优化器被做成当遇一些更加技巧性的结构时可能会不知所措从而生成比较保守的代码。

其实达夫设备是使用switch语句来控制进入循环的位置。

下面的程序是简单验证达夫设备的执行:

#include <stdio.h>

#include <stdlib.h>

int main(int argc,char**argv){

int n;

if(argc<2){

printf("not enough arugment\n");

return -1;

}

n=atoi(argv[1]);

switch(n){

case 0: do {printf("%d ",0);

case 1: printf("%d ",1);

case 2: printf("%d ",2);

case 3: printf("%d ",3);

case 4: printf("%d ",4);

}while(--n>0);

}

return 0;

}

什么是达夫设备(Duff's Device)第1张

从上面的输出结果我们可以清楚的看到,switch语句控制了进入循环的位置。

免责声明:文章转载自《什么是达夫设备(Duff's Device)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇YII2.0 在保存数据库内容会调用save()方法的注意事项嵌套矩形(动态规划)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

实用干货丨如何使用Prometheus配置自定义告警规则

前言普罗米修斯是一个用于监控和报警的开源系统。在普罗米修斯的术语中,它所监视的事物被称为目标。在本文中,我们将逐步展示如何安装Prometheus来监控/创建报警,并根据自定义事件配置自定义报警规则。当条件满足时,它将发出警报集成Alertmanager来处理客户端应用程序发送的警报。警报管理器将与发送警报通知的电子邮件帐户集成。了解普罗米修斯操作员根据普罗...

当微信小程序遇到AR(二)

当微信小程序遇到AR,会擦出怎么样的火花?期待与激动......通过该教程,可以从基础开始打造一个微信小程序的AR框架,所有代码开源,提供大家学习。注册地址=˃注册成功之后,需要下载微信小程序开发工具。下载地址=˃目前笔者的开发环境是:Windows10下载的微信小程序版本为:RCv1.0.2.1909111 打开,微信开发者工具之后,会看到如下的页面。...

无法将您的Kindle连接到Wi-Fi网络怎么办-kindle无法连接wifi-kindle无法连接手机热点

问题描述:当连接到Wi-Fi或移动热点时,Kindle会弹出提示:如果我无法将您的Kindle连接到Wi-Fi网络,该怎么办。步骤1:通过USB数据线将Kindle连接到计算机。2.连接后,我电脑的磁盘将像一个USB闪存驱动器,Kindle磁盘将出现在其中。3.进入Kindle磁盘。在Kindle磁盘下,右键单击创建一个名为WIFI_NO_NET_PROBE...

【01】如何在XMind中排列自由主题

如何在XMind中安排免费主题。在XMind思维导图软件中,用户可以根据需要添加免费主题。然而,由于自由主题的灵活性,它并不整洁,与需要控制界面有序排列的用户相比,这会造成一定的麻烦。首先选择要组织的所有免费主题,单击,然后在下拉框中选择以安排免费主题。有六种排列方式:左对齐、垂直居中、右对齐、顶部对齐、水平居中和底部对齐。...

一分钟制作U盘版BT3

一分钟生产BT3U磁盘版本方便、快捷、简单、无效且不可退款。BT3磁盘版本,大约694MB,可以直接烧录,然后用CD引导进入BT3。连接如下:http://ftp.heanet.ie/mirrors/backtrack/bt3-final.isoU磁盘版本Bt3,约783MB,连接为:http://cesium.di.uminho.pt/pub/backtr...

解决fiddler开启后打开浏览器提示无法访问网络

在使用python接口测试的过程中,jupyter经常被用来调试python代码。因为jupyter的默认代理端口是8888,所以当它启用时,它会打开fiddler数据包捕获并打开浏览器,提示“无法访问网络”。这个问题主要是由港口冲突造成的。您可以在工具选项连接中修改端口号,修改它,然后单击“确定”重新启动fiddler...