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

板子的程序跑成功之后,弄几个可以检验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. }

复制代码

开一个串口的终端看输出咯,Baud为115200. 程序在不断地循环做同样的计算。

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

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

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

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

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

[原创]NUCLEO-F410RB 测评第一周: 运行尝试

(0)

相关推荐