打印
[STM32F7]

【STM32F767ZIT6测评】STM32F7与STM32F4运行速度对比测试分析

[复制链接]
18744|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 252669569 于 2016-8-22 01:43 编辑

       这里使用三块NUCLEO板子进行测试,分别是NUCLEO-F401RE,NUCLEO-F411RE,NUCLEO-F767ZI,选择两块F4芯片,主要是探讨相同框架下频率对于运算速度的影响,401和411的框架和DMIPS/MHz是相同的,F7由于架构的改变,速度的提升是更加显著的。
实物图:
芯片参数对比:
  
板子
  
最高主频MHz
DMIPS
DMIPS/MHz
浮点运行器
STM32F401
84
105
1.25
FPU
STM32F411
100
125
1.25
FPU
STM32F767
216
462
2.14
DPFPU
实验步骤:
F7:
     在官方STM32Cube_FW_F7固件STM32F767ZI-NucleoàExamplesàUART例程,使用KEIL5打开,打开Manage Run-time Environment,勾选DSP,如下图所示:
     这个时候会发现在Project中多了一个CMSIS,里面的库文件是arm_cortexM7lfsp_math.lib,相关的库文件区别如下:
在Drivers\CMSIS\Lib\ARM下:

  • arm_cortexM7lfdp_math.lib     (Little endian and Double Precision Floating Point Unit on Cortex-M7)
  • arm_cortexM7lfsp_math.lib (Little endian and Single     Precision Floating Point Unit on Cortex-M7)
  • arm_cortexM7l_math.lib     (Little endian on Cortex-M7)
  • arm_cortexM4lf_math.lib     (Little endian and Floating Point Unit on Cortex-M4)
  • arm_cortexM4l_math.lib     (Little endian on Cortex-M4)
      也就是说调用的库是单精度浮点运算的,无法使用双精度浮点运算。解决办法是在Option的Device中选择另外一种芯片然后再选回来就可以了,具体可以参考这篇帖子:STM32F767ZI如何开启双精度浮点运算:bbs.21ic.com/icview-1622220-1-1.html
      然后在OptionàC/C++的Define中添加ARM_MATH_CM7,__FPU_PRESENTF4。
      开启FPU的方法是在Option—>TargetàCode GenerationàFloatingPoint Hardware后面的下拉菜单中可以选择NotUsed,Use SinglePrecision, Use Double Precision。这是选择是否使用浮点运算器,是单精度还是双精度的。
      由MATLAB随机生成32个浮点数,为了结果更加准确分别对这32个数字进行10000次乘法运算和1000次三角函数运算,测试的项目包括,整形运算,单精度浮点运算,DSP库单精度浮点运算,双精度浮点运算,三角函数运算,DSP库三角函数运算,通过Floating Point Hardware的选项来切换使用的浮点运算库。
测试主要程序:
测试数据:
#define MAX_BLOCKSIZE   32//测试数据个数
        //单精度浮点测试数据
float32_t testInput_f32[MAX_BLOCKSIZE] =
{
  -1.244916875853235400f,  -4.793533929171324800f,   0.360705030233248850f,   0.827929644170887320f,  -3.299532218312426900f,   3.427441903227623800f,   3.422401784294607700f,  -0.108308165334010680f,
   0.941943896490312180f,   0.502609575000365850f,  -0.537345278736373500f,   2.088817392965764500f,  -1.693168684143455700f,   6.283185307179590700f,  -0.392545884746175080f,   0.327893095115825040f,
   3.070147440456292300f,   0.170611405884662230f,  -0.275275082396073010f,  -2.395492805446796300f,   0.847311163536506600f,  -3.845517018083148800f,   2.055818378415868300f,   4.672594161978930800f,
  -1.990923030266425800f,   2.469305197656249500f,   3.609002606064021000f,  -4.586736582331667500f,  -4.147080139136136300f,   1.643756718868359500f,  -1.150866392366494800f,   1.985805026477433800f
};
//双精度浮点测试数据
float64_t testInput_f64[MAX_BLOCKSIZE] =
{
  -1.244916875853235400,  -4.793533929171324800,   0.360705030233248850,   0.827929644170887320,  -3.299532218312426900,   3.427441903227623800,   3.422401784294607700f,  -0.108308165334010680,
   0.941943896490312180,   0.502609575000365850,  -0.537345278736373500,   2.088817392965764500,  -1.693168684143455700,   6.283185307179590700,  -0.392545884746175080f,   0.327893095115825040,
   3.070147440456292300,   0.170611405884662230,  -0.275275082396073010,  -2.395492805446796300,   0.847311163536506600,  -3.845517018083148800,   2.055818378415868300f,   4.672594161978930800,
  -1.990923030266425800,   2.469305197656249500,   3.609002606064021000,  -4.586736582331667500,  -4.147080139136136300,   1.643756718868359500,  -1.150866392366494800f,   1.985805026477433800
};
//32位整形测试数据
int32_t testInput_q32[MAX_BLOCKSIZE] =
{
  244916875,  171324800,   33248850,   70887320, 83124269,   27623800,   94607700, 4010680,
  240312180,  500365850,  36373500,  965764500,  143455700,  79590700,  46175080,   278930951,
56292300,   884662230, 39607010,  446796300,   65066009,  83148808,   868300111,  78930800,
266425800,  6249500,   64021000,  586736582,  36136300,  868359500,   664948001,  77433800
};
测试函数:
while (1)
  {
                //1000次sincos运算不使用DSP库耗时
                        tickstart=HAL_GetTick();
        for(int j=0;j<1000;j++){
         for(int i=0; i< blockSize; i++)
                {
    cosOutput = cos(testInput_f32[i]);
    sinOutput = sin(testInput_f32[i]);
                }
        }
        tick_sincos=HAL_GetTick()-tickstart;
                        //1000次sincos运算使用DSP库耗时
                tickstart=HAL_GetTick();
        for(int j=0;j<1000;j++){
         for(int i=0; i< blockSize; i++)
                {
    cosOutput = arm_cos_f32(testInput_f32[i]);
    sinOutput = arm_sin_f32(testInput_f32[i]);
                }
        }
        tick_sincos_dsp=HAL_GetTick()-tickstart;
                //10000次32位数据相乘运算耗时
                tickstart=HAL_GetTick();
        for(int j=0;j<10000;j++){
         for(int i=0; i< blockSize; i++)
                {
    Output_q32 = testInput_q32[i]*testInput_q32[i];
                }
        }
        tick_mult_q32=HAL_GetTick()-tickstart;
                //10000次单精度数据相乘运算耗时
                        tickstart=HAL_GetTick();
        for(int j=0;j<10000;j++){
         for(int i=0; i< blockSize; i++)
                {
    Output_f32 = testInput_f32[i]*testInput_f32[i];
                }
        }
        tick_mult_f32=HAL_GetTick()-tickstart;
        //10000次双精度数据相乘运算耗时
                        tickstart=HAL_GetTick();
        for(int j=0;j<10000;j++){
         for(int i=0; i< blockSize; i++)
                {
    Output_f64 = testInput_f64[i]*testInput_f64[i];
                }
        }
        tick_mult_f64=HAL_GetTick()-tickstart;
                //10000次单精度数据相乘运算使用DSP库耗时
                tickstart=HAL_GetTick();
                for(int j=0;j<10000;j++){
                         arm_mult_f32(&testInput_f32[0], &testInput_f32[0], &Output_f32_A[0], blockSize);
                }
                tick_mult_f32_dsp=HAL_GetTick()-tickstart;
                //10000次for循环耗时
                        tickstart=HAL_GetTick();
                for(int j=0;j<10000;j++){
                }
                tickfor=HAL_GetTick()-tickstart;
                //输出测试结果
                printf("tick_sincos=%d,tick_sincos_dsp=%d,tick_mult_q32=%d,tick_mult_f32=%d,tick_mult_f64=%d,tick_mult_f32_dsp=%d\n\r",tick_sincos,tick_sincos_dsp,tick_mult_q32,tick_mult_f32,tick_mult_f64,tick_mult_f32_dsp);
  }
完整函数和使用方法请见帖子最下方github链接。
F4:
两款F4芯片的实验步骤与F7类似,使用官方的M4库选择对应芯片的UART例程,OptionàC/C++的Define中添加ARM_MATH_CM4就可以了。
最后将串口输出数值记录下来。
实验结果:
  
芯片和运算库
  
整形运算
单精度浮点
单精度浮点DSP
双精度浮点
三角函数
DSP三角函数
401null
28
201
210
898
3012
417
401sf
28
39
29
905
3213
43
411null
23
169
177
754
2561
351
411sf
23
33
24
761
2738
37
767null
6
59
57
210
793
130
767sf
6
8
5
213
837
19
767df
6
7
5
18
79
19
注:尾缀null代表浮点运算器选择Not Used,尾缀sf代表Use Single Precision,尾缀df代表Use DoublePrecision,表中的数据代表耗时,单位ms
结论:
1.      相同框架的F4芯片,所有类型(整形,浮点,DSP库)的运算速度与芯片的频率成正比
2.      F4芯片使用单精度浮点运算器,在单精度浮点的运算上比不使用的提高5倍以上,对双精度没有影响,DSP库三角函数速度调高9倍以上,DSP的单精度浮点运算有提高明显,不过相对于直接使用并没有太大的提升,不知道在大量数据的情况下会不会有所改善。
3.       F7芯片使用单精度浮点运算器,在单精度浮点的运算上比不使用的提高7倍以上,对双精度没有影响,DSP库三角函数速度调高6倍以上,DSP的单精度浮点运算有提高明显,不过相对于直接使用并没有太大的提升
4.      F7芯片使用双精度浮点运算器,在双精度浮点的运算上比不使用的提高11倍以上,对单精度没有影响,三角函数的运算提高10倍以上。
5.      可以推测出,如果M4芯片的处理速度也达到216M,开启FPU,那么相同频率下的M7在32位整数相乘上速度是M4的1.8倍,单精度浮点:2.1倍,单精度DSP:2.2倍,双精度19.6倍,三角函数16倍,DSP三角函数不变。
以上测试方法并不是十分专业,欢迎拍砖,测试所有的代码均放到github托管:
github.com/flyloong/STM32F7_F4_Performance_test
欢迎重复测试,提出异议。

沙发
mmuuss586| | 2016-8-22 10:09 | 只看该作者
谢谢分享;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

9

帖子

1

粉丝