3
回答
达夫设备(duff device)效率
华为云7大明星产品0元使用! >>>   

代码如下,传说中这段代码可以很省时间,可是为什么测试结果显示,他与普通的for和while差不多呢? 我有尝试关闭编译优化,数据也很大,from数组大约有两百吧,循环send_duff代码10000次。

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);
        }
}

 

 

 

<无标签>
举报
yandong
发帖于5年前 3回/973阅
共有3个答案 最后回答: 5年前

case 你可以看成 label这种东西。我喷一句,这种代码非常傻逼。

如果说省时间,类似这种代码的设计,主要是想通过减少循环体判断的费用。这个函数的特点是要考虑长度的情况和两个地址偏移量的情况。可以整体判断,跳转实现。我一会写个代码贴上来,你可以参考一下。

 

--- 共有 1 条评论 ---
yandong嗯嗯,谢谢鬼哥了 5年前 回复

SORRY。才发现是新电脑,我的开发工具,和自己的测试库都没有到位。没办法写代码测试验证。

基本思路如下:

如果小于4个传输,则直接char ->char,就是

while (count-- > 0){

*to++=*from++;

}

其他情况使用32位,或64位进行传递。

这里有问题,在于to , from,未必是32位对齐的。所以导致两个需要解决的事情。

1、起始位置的赋值和修正。

2、在循环中,实际是对to ,from所对应的区间,32位或64位对齐的数据进行移位整合。通过两个数据宽度的数据,移位并与上屏蔽位,再或 成 一个可以放到to区间,32位或64位对齐的操作。

最后,需要注意,尾巴,尾巴一般好处理,把to的原始数据读上来,然后作为内容,移位,增补到最后一次要写入的32位或64位对齐的数据中。

 

上述算法,无论是C,ARM下,还是DSP的汇编,我都写过。没任何问题。其实很多DMA的调度策略也是相同的。他们内部有个数据移位器,用于针对目标指针(对齐)的,将源数据(也对齐的),进行整体位置修正。

--- 共有 2 条评论 ---
yandong鬼哥,这段话真心没看懂,能否贴点代码? 5年前 回复
yandong说说我的理解,主体思路上一次读取4或者8个char。但是其他的就没看懂。。。-_- 5年前 回复

@yandong ,大体思路如下,


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

顶部