板子的程序跑成功之后,弄几个可以检验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)。主程序就这样写了
- #include<string.h>
- #include "stm32f4xx.h"
- #include "md5.h"
- #include "text.c"
- int main(void)
- {
- unsigned char md5[16];
- // FLASH->ACR = FLASH_ACR_ICEN|FLASH_ACR_DCEN;
- memcpy(ram_text, rom_text, sizeof(rom_text));
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // enable GPIO port A clock
- __NOP();
- GPIOA->MODER = GPIO_MODER_MODER14_1|GPIO_MODER_MODER13_1 // PA14, PA13 AF (SWD pins)
- |GPIO_MODER_MODER10_1|GPIO_MODER_MODER9_1 // PA10, PA9 AF (UART)
- |GPIO_MODER_MODER5_0; // PA5 as general output (LED)
- GPIOA->AFR[1] = 0x00000770; // AF1 for PA9,PA10; AF0 for others
- uart_setup();
- uart_wstr("Hello from F410\r\n");
- RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; // enable timer 5
- while(1)
- {
- static char a=0;
- unsigned int t;
- char str[32];
- TIM5->CNT = 0;
- TIM5->CR1 = TIM_CR1_CEN;
- md5_buffer(rom_text, sizeof(rom_text), md5);
- t=TIM5->CNT;
- TIM5->CR1 = 0;
- uart_wstr("MD5 ROM data at 0x");
- uart_whex(rom_text);
- uart_wstr(", time ");
- uart_wdec(t);
- uart_wstr("\r\n(");
- uart_hexdump(md5,16);
- uart_wstr(")\r\n");
- TIM5->CNT = 0;
- TIM5->CR1 = TIM_CR1_CEN;
- md5_buffer(ram_text, sizeof(rom_text), md5);
- t=TIM5->CNT;
- TIM5->CR1 = 0;
- uart_wstr("MD5 RAM data at 0x");
- uart_whex(ram_text);
- uart_wstr(", time ");
- uart_wdec(t);
- uart_wstr("\r\n(");
- uart_hexdump(md5,16);
- uart_wstr(")\r\n");
- if(a==0)
- {
- GPIOA->BSRRL = (1<<5);
- a=1;
- }
- else
- {
- GPIOA->BSRRH = (1<<5);
- a=0;
- }
- }
- }
开一个串口的终端看输出咯,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算法还不能完全展现区别。后面再继续吧……