【大狗子笔记】嵌入式C之捋一下达夫设备
在看C指针的时候,看到了一段诡异的代码,名叫“达夫设备”。
达夫设备其实就是实现了数据拷贝的功能,将数组from的数据,copy到数组to。而相较于普通copy方式,达夫设备能极大的缩小大数据量的copy时间。
我先大概描述一下它的实现原理:达夫设备主要是通过减少copy循环过程中的条件判断次数,来提高执行效率,缩短时间。
一个简单的比喻:有两个仓库,from和to。打工人需要把100袋大米由from搬运到to。一次搬一袋,每次搬运都要和库房管理核对搬运的次数,保证100袋大米数量无误。这样就是需要搬运100次,核对100次。假设搬运的的时间和去找库房管理核对的时间是一样的,都需要5分钟,则全部搬运完需要1000分钟(默认工人中途不能休息),这样的效率显然不高。而达夫设备的方案是:找一个工人小队来干活(假设有8人),这样一次就能搬运8袋米。100除以8得12余4,则需要搬运小队搬运13次(第一次先来4人,后面12次全员出动),核对13次即可。搬运时间为130分钟。
理解了原理,代码就很容易看懂了,代码如下:
1 int duffs_device(char *from, char *to, int count) 2 { 3 { 4 int n = (count + 7) / 8; 5 6 switch(count % 8) 7 { 8 case 0: do { *to++ = *from++; 9 case 7: *to++ = *from++; 10 case 6: *to++ = *from++; 11 case 5: *to++ = *from++; 12 case 4: *to++ = *from++; 13 case 3: *to++ = *from++; 14 case 2: *to++ = *from++; 15 case 1: *to++ = *from++; 16 } while(--n > 0); 17 } 18 } 19 return count; 20 }
这代码的结构显得非常诡异,把一个switch语句和一个do-while语句糅合在了一起。虽然看起来有些另类,但这段代码确实可以被编译通过。
这段代码的主体是那个do-while循环,不过这个循环里面第一个被执行的,并不一定是靠近do的那一行代码。哪一行代码会最先被执行,取决于前面的switch-case语句。
将count = 100带入这段代码,走一遍流程,就可以很简单理解这段代码的内容了:
1.count = 100, 则n = 13, 且count % 8 = 4;
2.则有 switch(4),那接下来就会执行case 4里面的代码,而且这里switch-case语句只会生效一次,用过就没了(相当于将switch和case相关的字符移除掉);
3.执行完case 4里面的*to++ = *from++代码之后,由于switch-case语句失效,代码会顺序执行,接着执行后面3行*to++ = *from++代码,然后到 while(--n > 0);
4.执行完 while(--n > 0)之后,n的值为12,则do-while还需要循环12次,而do-while里面的有效内容已经变成8行*to++ = *from++;
5.那整个程序就是执行了(4+8*12)=100次代码*to++ = *from++,做了13次n值比较,刚好copy完100个元素。
再来看看常规的数组元素copy代码,很显然,这段代码同样是进行了100次数据复制,但是同时也进行了100次i的数值比较,相较于前面的达夫设备的13次,这里的效率明显低了。
1 int normal_copy(char *from, char *to, int count) 2 { 3 int i = 0; 4 for(i = 0; i < count; i++) 5 { 6 to[i] = from[i]; 7 } 8 return i; 9 } 10
当需要copy的元素越多,使用达夫设备之后提升的速度就越明显。至此,达夫设备就捋完一遍了,不难理解,但却是很奇思妙想。

【本文来自大狗子的博客园,作者:风华绝代王嘉然,请访问:https://www.cnblogs.com/Donny-NXP/p/14424046.html】

浙公网安备 33010602011771号