达夫设备/达夫算法(Duff's Device)
主要是下面的代码:
|
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; } |
从上面的输出结果我们可以清楚的看到,switch语句控制了进入循环的位置。 |
达夫设备/达夫算法(Duff's Device)的更多相关文章
- 冷知识:达夫设备(Duff's Device)效率真的很高吗?
ID:技术让梦想更伟大 作者:李肖遥 wechat链接:https://mp.weixin.qq.com/s/b1jQDH22hk9lhdC9nDqI6w 相信大家写业务逻辑的时候,都是面向if.el ...
- 达夫设备(Duff's Device)
达夫设备设备是一段非常巧妙,看起来非常诡异的c代码,它可以很大的提高程序执行的效率(本文将试验),达夫设备的来源我就不说了,我们来分析一下. 达夫设备是考虑到我们一般用for或者while循环的时候, ...
- 高性能JavaScript 达夫设备
前言 在<高性能JavaScript>一书的第四章算法和流程控制中,提到了减少迭代次数加速程序的策略—达夫设备(Duff's device).达夫设备本身很好理解,但是其效果是否真的像书中 ...
- 达夫设备之js
最近阅读<高性能JavaScript>时,在书中的“达夫设备“ . 对此,有些感悟,同时有些疑问,希望看到的朋友,能帮忙解释下,在此先提前感谢了. 1. 先说自己的理解吧: ”达夫设备“的 ...
- 【转】Duff's Device
在看strcpy.memcpy等的实现发现用了内存对齐,每一个word拷贝一次的办法大大提高了实现效率,参加该blog(http://totoxian.iteye.com/blog/1220273). ...
- 读高性能JavaScript编程 第四章 Duff's Device
又要开始罗里吧嗦的 第四章 Summary 了. 这一次我尽量精简语言. 如果你认为 重复调用一个方法数次有点辣眼睛的话 比如: function test(i){ process(i++); pr ...
- Openck_Swift源代码分析——添加、删除设备时算法详细的实现过程
1 初始加入设备后.上传Object的详细流程 前几篇博客中,我们讲到环的基本原理即详细的实现过程,加入我们在初始创建Ring是执行例如以下几条命令: •swift-ring-builder obj ...
- OpenStack_Swift源代码分析——创建Ring及加入�设备源代码算法具体分析
1 创建Ring 代码具体分析 在OpenStack_Swift--Ring组织架构中我们具体分析了Ring的具体工作过程,以下就Ring中添加�设备,删除设备,已经又一次平衡的实现过程作具体的介绍. ...
- Nova: 虚机的块设备总结 [Nova Instance Block Device]
和物理机一样,虚拟机包括几个重要的部分:CPU.内存.磁盘设备.网络设备等.本文将简要总结虚机磁盘设备有关知识. 1. Nova boot CLI 中有关虚机块设备的几个参数 nova boot CL ...
随机推荐
- 【转】VS2010/MFC编程入门之八(对话框:创建对话框类和添加控件变量)
原文网址:http://www.jizhuomi.com/software/153.html 前两讲中鸡啄米为大家讲解了如何创建对话框资源.创建好对话框资源后要做的就是生成对话框类了.鸡啄米再声明下, ...
- HDU-4515 小Q系列故事——世界上最遥远的距离
小Q系列故事——世界上最遥远的距离 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) ...
- 用Oracle的TRIM函数去除字符串首尾指定字符
去掉首尾空格 SELECT TRIM(' abc '), ltrim(' abc '), rtrim(' abc ') FROM dual; 去掉首尾的其他字符 SELECT /*TRIM(';a;b ...
- [liu yanling]测试用例的设计方法
一.功能测试 1.对话框测试输入进行测试.包括中文字符.英文字符.数字字符.特殊字符.及几种字符的组合. 2.对界面可操作按钮进行测试.包括[新增(N)][保存(S)][修改(M) ...
- 未能找到类型或命名空间“Compare”
在用vs2012 .net Framework4.5 Mvc3做一个MVCMusicStore 的例子时,遇到这样一个问题 解决办法: 具体原因也不是很清楚,据说是引用Compare做验证时会有二 ...
- 【wuzhicms】apache 设置禁止访问某些文件或目录
[apache配置禁止访问] 1. 禁止访问某些文件/目录 增加Files选项来控制,比如要不允许访问 .inc 扩展名的文件,保护php类库: <Files ~ "\.inc$&qu ...
- Windows Azure -Azure 网站、云服务和虚拟机的对比
Azure 网站.云服务和虚拟机对比 概述 Azure提供了几种方法来承载网站: Azure网站.云服务和虚拟机.本文帮助您了解选项和为您的Web应用程序做出正确选择. Azure网站是大多数web应 ...
- ZOJ-3725 Painting Storages DP
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3725 n个点排列,给每个点着色,求其中至少有m个红色的点连续的数 ...
- XXX 用户 is not in the sudoers file. This incident will be reported 的问题解决方案
说的是,这种问题,是出现在ubuntu系统里. root@SparkSingleNode:/usr/local/jdk# pwd /usr/local/jdk root@SparkSingleNode ...
- 如何用jQuery实现在鼠标滚动后导航栏保持固定
要实现如下效果,鼠标滚动后,上方导航栏置顶固定 关键html代码: <div class="header-bottom"> <div class="co ...
