OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6019|回复: 15

(讨论)ARM的DSP 函数效率

[复制链接]

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
发表于 2016-5-23 10:22:34 | 显示全部楼层 |阅读模式
1金钱
       我目前用f407改造一款原来公司用dsp完成的产品。       不知道论坛的网友有没有用过ARM的DSP核做过算法方面的评估。我之前做DSP算法评估的流程,一个算法写好后要先评估用了多少个乘加运算,内存开销,最后在DSP里面进行流水线优化。考核时间一般用DSP内部的两个“心跳计数器”“TSCH”“TSCL”计算实际的指令开销。
       现在用ARM,找不到精确定义时间的寄存器,所以我用调试器的那个“sec”计算运行的时间长短的。但是用了几次我发现不是太准,好像要比实际情况慢不少。我想问下坛友有什么好的方法精确的确定某段程序运行时间长短,tim定时器里面的cnt行不行。

      另外还有一个问题,我看了芯片介绍f407有硬件浮点支持,还有不少dsp的库函数支持。我周末做了一实验,考察了一下两列浮点数连乘的运行时间。

      1.for(i=0;i<6;i++)
                re += *(in-i) * fircoeff;     这个在“sec”里面看了耗时是0.0000136

       dsp lib里面的函数改造了一下
       2.arm_add_f32(&IN[0], &fircoeff[0], &test[6], 6);   这个在“sec”里面看了耗时是0.0000187
      也就是说DSP的库函数还没有直接连乘的效率高,而且这个只是连乘的结果还没有进行累加,这个让我很费解。我觉得应该不太可能。不知道问题出在哪里。
      
      因为用DSP做的话要优化流水小,展开部分循环,输入的参数要双字对齐,告诉编译器这个循环最大和最小循环次等信息。一个循环的代码要写成这样:
    _nassert(((int)x & 7) ==0);
    _nassert(((int)y & 7) ==0);
    _nassert(nr % 8 == 0);

    #pragma MUST_ITERATE(2,4096,2);
    #pragma UNROLL(16);

        for(i=0;i<nr;i++)
        {
                *(y+i) += m *  *(x - i);
        }

       我不清楚ARM上做算法优化是不是也需要一些技巧。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2016-5-23 14:57:18 | 显示全部楼层
没用过F4的DSP功能,但是感觉第一个计算方法,编译器会优化,所以会快,可以用浮点数相乘做一次测试
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-5-23 15:35:00 | 显示全部楼层
zuozhongkai 发表于 2016-5-23 14:57
没用过F4的DSP功能,但是感觉第一个计算方法,编译器会优化,所以会快,可以用浮点数相乘做一次测试

我觉得如果直接编译器计算的时间都比库函数快的话,这些“arm_add_f32”就完全没意义了,DSP里面这种库函数一定比编译器的优化要快很多的。所以我不理解,或者ARM中用这些库函数还需要做另外一些处理?
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-5-23 17:05:43 | 显示全部楼层
zuozhongkai 发表于 2016-5-23 14:57
没用过F4的DSP功能,但是感觉第一个计算方法,编译器会优化,所以会快,可以用浮点数相乘做一次测试

目前还是需要用arm改的,我这里测试完了在总结一下arm的dsp核和dsp的区别。
回复

使用道具 举报

5

主题

76

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
325
金钱
325
注册时间
2016-5-25
在线时间
86 小时
发表于 2016-5-25 16:16:37 | 显示全部楼层
我现在做的项目也是用F4的DSP来跑算法,也有很多盲区!以后还望指点
笑着熬下去@_@
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-5-25 17:49:09 | 显示全部楼层
本帖最后由 yyx112358 于 2016-5-25 17:54 编辑

DSP库函数通常来说计算之前做了很多初始化,主要是在进行4字节对齐。所以这个只有在次数很大时才能体现优势
不过arm_add_f32这个库函数应该确实没什么性能上的优化,主要是方便吧。下面是源码
[mw_shl_code=c,true]void arm_add_f32(
float32_t * pSrcA,
float32_t * pSrcB,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counter */
#ifndef ARM_MATH_CM0_FAMILY
/* Run the below code for Cortex-M4 and Cortex-M3 */
float32_t inA1, inA2, inA3, inA4; /* temporary input variabels */
float32_t inB1, inB2, inB3, inB4; /* temporary input variables */
/*loop Unrolling */
blkCnt = blockSize >> 2u;
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while(blkCnt > 0u)
{
/* C = A + B */
/* Add and then store the results in the destination buffer. */
/* read four inputs from sourceA and four inputs from sourceB */
inA1 = *pSrcA;
inB1 = *pSrcB;
inA2 = *(pSrcA + 1);
inB2 = *(pSrcB + 1);
inA3 = *(pSrcA + 2);
inB3 = *(pSrcB + 2);
inA4 = *(pSrcA + 3);
inB4 = *(pSrcB + 3);
/* C = A + B */ (1)
/* add and store result to destination */
*pDst = inA1 + inB1;
*(pDst + 1) = inA2 + inB2;
*(pDst + 2) = inA3 + inB3;
*(pDst + 3) = inA4 + inB4;
/* update pointers to process next samples */
pSrcA += 4u;
pSrcB += 4u;
pDst += 4u;
/* Decrement the loop counter */
blkCnt--;
}
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
** No loop unrolling is used. */
blkCnt = blockSize % 0x4u;
#else
/* Run the below code for Cortex-M0 */
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
while(blkCnt > 0u)
{
/* C = A + B */
/* Add and then store the results in the destination buffer. */
*pDst++ = (*pSrcA++) + (*pSrcB++);
/* Decrement the loop counter */
blkCnt--;
}
}[/mw_shl_code]

回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-5-25 18:24:56 | 显示全部楼层
没用过,不过我认为肯定是ARM的dsp库效率最高,没有比ARM更懂它的内核的了

http://www.keil.com/pack/doc/CMSIS/DSP/html/index.html
坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-5-26 09:06:07 | 显示全部楼层
xkwy 发表于 2016-5-25 18:24
没用过,不过我认为肯定是ARM的dsp库效率最高,没有比ARM更懂它的内核的了

http://www.keil.com/pack/do ...

这个还是得实际测试一下,目前这几个测试确实没看出来太大的优势。我会稍微补充下接下来的测试结果。
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-6-3 17:06:07 | 显示全部楼层
jeff_梁 发表于 2016-5-25 16:16
我现在做的项目也是用F4的DSP来跑算法,也有很多盲区!以后还望指点

好的,谢谢你。有问题多交流我搞dsp比较多,arm的dsp核也不是很懂。
回复

使用道具 举报

5

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
200
金钱
200
注册时间
2016-5-29
在线时间
5 小时
发表于 2016-6-4 16:10:01 | 显示全部楼层
DSP没有涉及,学习了
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-6-6 10:47:29 | 显示全部楼层
xkwy 发表于 2016-5-25 18:24
没用过,不过我认为肯定是ARM的dsp库效率最高,没有比ARM更懂它的内核的了

http://www.keil.com/pack/do ...

用arm的库函数测试1024点fft,直接用的st官方的demo。开了浮点支持。

                /* Process the data through the CFFT/CIFFT module */
                arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);
       
                /* Process the data through the Complex Magnitude Module for  
                calculating the magnitude at each bin */
                arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);


                /* Calculates maxValue and returns corresponding BIN value */
                arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);

                /* ----------------------------------------------------------------------
                ** Loop here if the signals fail the PASS check.
                ** This denotes a test failure
                **


用定时器观察耗时6ms左右。我在6748上用ti的库函数测试是不到10000周期。6748是450MHz,所以在ti上跑大概是2.2us,两者差了300倍。
QQ图片20160606104529.png
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-6-6 10:48:15 | 显示全部楼层
jeff_梁 发表于 2016-5-25 16:16
我现在做的项目也是用F4的DSP来跑算法,也有很多盲区!以后还望指点

好的,有问题多交流。
回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-6-6 12:19:19 | 显示全部楼层
czdspeed 发表于 2016-6-6 10:47
用arm的库函数测试1024点fft,直接用的st官方的demo。开了浮点支持。

                /* Process the data throug ...

额,我的意思是运行在ARM芯片上的所有库中,官方的库效率最高,


毕竟ARM和DSP有本质的区别,这么对比下来,太残暴了

就好比拿iPhone和砖头对比硬度,并不能说明孰强孰劣
坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-6-6 16:39:59 | 显示全部楼层
xkwy 发表于 2016-6-6 12:19
额,我的意思是运行在ARM芯片上的所有库中,官方的库效率最高,

所以我觉得是不是哪里没有开启,dsp是450MHz,arm168MHz,即使dsp下降了3倍。也差了100倍,应该不太可能啊。
回复

使用道具 举报

3

主题

347

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
2078
金钱
2078
注册时间
2014-12-19
在线时间
710 小时
发表于 2016-6-6 16:52:53 | 显示全部楼层
隔壁安富莱的DSP教程,参考一下吧
http://pan.baidu.com/s/1gejDTOB
回复

使用道具 举报

36

主题

256

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2016-4-20
在线时间
169 小时
 楼主| 发表于 2016-6-6 16:59:06 | 显示全部楼层
lvehe 发表于 2016-6-6 16:52
隔壁安富莱的DSP教程,参考一下吧
http://pan.baidu.com/s/1gejDTOB

谢谢,我抽时间看看。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 11:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表