[原创] NUCLEO-F410RB 测评第二周之MD5速度测试

cruelfox   2015-12-10 00:03 楼主
板子的程序跑成功之后,弄几个可以检验M4处理能力的程序测试下吧,也跟手头的NUCLEO-F091RC对比一下。用什么做测试对比呢?顺手拿个MD5算法的C程序(从util-linux源代码包里面搜刮出来的),跑一下看看运行时间。因为ARM是32位,这个md5.c移植过来很顺利,我使用其中的md5_buffer()函数来计算一块数据的MD5校验码。要处理的数据则存放到ROM中,也在RAM中复制一份,作为对比。STM32F410RB 和 STM32F091RC 都有 32kB 的SRAM,所以我取了个22073字节的数据块是没有问题的。

为了测试运行时间,我就启用了一个32-bit的定时器。在F410上,用Timer5, 而在F091上,则用Timer2. 因为其它的Timer都是16-bit的了。设置并启用Timer之后,就调用 md5_buffer() 函数进行一次计算,返回后读取Timer的CNT寄存器值,则得到消耗掉的机器周期个数。把结果用文本形式从串口输出(使用USART1)。主程序就这样写了
  1. #include<string.h>

  2. #include "stm32f4xx.h"
  3. #include "md5.h"

  4. #include "text.c"

  5. int main(void)
  6. {

  7.     unsigned char md5[16];

  8. //  FLASH->ACR = FLASH_ACR_ICEN|FLASH_ACR_DCEN;

  9.     memcpy(ram_text, rom_text, sizeof(rom_text));

  10.     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;    // enable GPIO port A clock
  11.     __NOP();

  12.     GPIOA->MODER = GPIO_MODER_MODER14_1|GPIO_MODER_MODER13_1   // PA14, PA13 AF (SWD pins)
  13.                 |GPIO_MODER_MODER10_1|GPIO_MODER_MODER9_1   // PA10, PA9 AF (UART)
  14.                 |GPIO_MODER_MODER5_0;   // PA5 as general output (LED)
  15.     GPIOA->AFR[1] = 0x00000770; // AF1 for PA9,PA10; AF0 for others

  16.     uart_setup();
  17.     uart_wstr("Hello from F410\r\n");

  18.     RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; // enable timer 5

  19.     while(1)
  20.     {
  21.         static char a=0;
  22.         unsigned int t;
  23.         char str[32];

  24.         TIM5->CNT = 0;
  25.         TIM5->CR1 = TIM_CR1_CEN;
  26.         md5_buffer(rom_text, sizeof(rom_text), md5);
  27.         t=TIM5->CNT;
  28.         TIM5->CR1 = 0;
  29.         uart_wstr("MD5 ROM data at 0x");
  30.         uart_whex(rom_text);
  31.         uart_wstr(", time ");
  32.         uart_wdec(t);
  33.         uart_wstr("\r\n(");
  34.         uart_hexdump(md5,16);
  35.         uart_wstr(")\r\n");

  36.         TIM5->CNT = 0;
  37.         TIM5->CR1 = TIM_CR1_CEN;
  38.         md5_buffer(ram_text, sizeof(rom_text), md5);
  39.         t=TIM5->CNT;
  40.         TIM5->CR1 = 0;
  41.         uart_wstr("MD5 RAM data at 0x");
  42.         uart_whex(ram_text);
  43.         uart_wstr(", time ");
  44.         uart_wdec(t);
  45.         uart_wstr("\r\n(");
  46.         uart_hexdump(md5,16);
  47.         uart_wstr(")\r\n");

  48.         if(a==0)
  49.         {
  50.             GPIOA->BSRRL = (1<<5);
  51.             a=1;
  52.         }
  53.         else
  54.         {
  55.             GPIOA->BSRRH = (1<<5);
  56.             a=0;
  57.         }
  58.     }
  59. }
IMG_2384.jpg
开一个串口的终端看输出咯,Baud为115200. 程序在不断地循环做同样的计算。
output.png

结果如下,上面的窗口是GCC-4.8.4  -O2 优化选项编译后的运行时间,文本数据放在ROM中,226487 周期;文本数据放在RAM中,232311周期。我还没有弄明白为什么数据在ROM反而更快?按说D-BUS和I-BUS分别连接在SRAM和Flash的话总线是没有访问冲突的应该更快啊……

试下不同的优化级别呢,在 -Os 优化选项下,数值分别变成 239251239236, ROM和RAM差别很微小但RAM终于胜出了,在 -O 优化选项下最慢,分别是 243758240991 (这回RAM中又快了一点);在 -O3 优化选项下,分别是 226434232267. -O2和-O3编译的结果其实速度差别也不到 0.1%. 但 -O2 和 -Os 优化的区别就超过 5%了。

尝试下把指令集从 -mcpu=cortex-m4 改成 -mcpu=cortex-m0, 运行速度明显降低。在最快的 -O3 优化下,消耗周期数分别是 333130335526,  也就是 采用 M4 指令集整体速度比 M0 的指令集快了近 50%. MD5算法大量的是逻辑运算,如果是算术运算这个差距可能更大。在 -Os 优化下,消耗周期数分别是 336929 337261, 仍然有 1.4 倍的速度优势.

和 F091 的对比又如何呢?在F091上,数据放在 ROM 和 RAM 中,运行的结果是一样的,这是单一总线的表现。在最快的 -O3 选项下,消耗周期 341915; 在 -Os 选项下,消耗周期 347795. 因此即使限制在同样的指令集,M4核也比M0有2%~3%的速度提升。

当然,仅仅MD5算法还不能完全展现区别。后面再继续吧……

    md5_test_proj.zip (2015-12-10 00:03 上传)

    254.15 KB, 阅读权限: 5, 下载次数: 54

回复评论 (4)

哇  关注一下这个板子的指标
点赞  2015-12-10 09:20
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2015-12-10 09:36
牛牛牛,期待后续测试~~
gitee/casy
点赞  2015-12-10 12:20

圈粉了。。。

点赞  2020-11-8 21:46
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复