【大狗子笔记】嵌入式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的元素越多,使用达夫设备之后提升的速度就越明显。至此,达夫设备就捋完一遍了,不难理解,但却是很奇思妙想。

posted @ 2021-02-21 02:35  风华绝代王嘉然  阅读(177)  评论(0)    收藏  举报