达夫设备
http://www.oschina.net/question/583160_66329
void send_duff(char *to, char *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); } }
1、我们希望不通过一个char ,一个char的传递。尽可能利用已有可控的带宽。例如64位系统,我们就用64位传递。128位系统,就用128传递,当然这个和数据存储位置也有关系。有的系统,外部MEM到片上是32位的,而片内L2到TCM是64位的。而TCM到寄存器是128位的。同时你是 C语言设计程序,还是设计DMA等总线控制器的一部分也不一样。但基本精神不变,就是最大化的利用可控的软硬件资源。落到C程序上,就是尽可能使用编译器能支持的大位宽数据类型。
2、由于函数接口要求,对大位宽,例如64位或32位,没有任何约束,包括起始地址边界对齐问题和传输量的问题。因此需要分别对待。
3、首先需要关注传输量的问题。
4、其次关注起始地址偏移量不同的问题。
5、实际在循环中反复的,存在一个位移的事情,例如一次可传输64位,则需要两组64位数据,根据源地址,和目标地址偏移量的差值做适当位移,向左向右,需要根据实际偏移量哪个大,还有计算机的大数在前还是小数在前的情况,实际确定。
基本思想就是这样,不用担心数据COPY中存在移位等计算。计算机有pipeline的,数据预读和存储与这些计算都是可以并发操作的。所以整体性能远比char 一个个传的快。虽然char一个个传,如上面代码那样,看似干净,但落到实际系统执行时,也还是需要依次等待内部总线可利用。除非编译器自动识别,产生了DMA的机理操作。貌似除了特定书写规范的代码,按照编译器的要求来书写,否则编译器无法实现这种动态识别。
雨,静静的飘扬;
心,慢慢的行走;
程序人生,人生迈进。