达夫设备

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的机理操作。貌似除了特定书写规范的代码,按照编译器的要求来书写,否则编译器无法实现这种动态识别。



原文地址:https://www.cnblogs.com/xuddong/p/3071732.html