I was looking for a few bytes extra flash today, and realized that some old AVR code I had, which used uint8_t
extensively for loop counters and indexes (dealing with small arrays) might not be all that efficient on the STM32 Cortex-M3.
So, I went over the code and replaced all places where the size of the counter wasn’t really actually important, and made some comparisons. I was compiling the exact same c file in both cases, with only a type def changing between runs.
Compiler versions and flags
platform | gcc version | cflags |
---|---|---|
AVR | avr-gcc (GCC) 4.3.5 | -DNDEBUG -Wall -Os -g -ffunction-sections -fdata-sections -Wstrict-prototypes -mmcu=atmega168 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums |
STM32 | arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.6.2 20120316 (release) [ARM/embedded-4_6-branch revision 185452] | -DNDEBUG -Wall -Os -g -ffunction-sections -fdata-sections -Wstrict-prototypes -fno-common -mcpu=cortex-m3 -mthumb |
And… here’s the results
counter type | avr-size | arm-none-eabi-size |
---|---|---|
unsigned int | 1318 | 844 |
uint8_t (original) | 1160 | 856 |
uint_least8_t | 1160 | 856 |
uint_fast8_t | 1160 | 844 |
int | 1330 | 820 |
int8_t | 1212 | 872 |
int_least8_t | 1212 | 872 |
int_fast8_t | 1212 | 820 |
I would personally say that it looks like ARM still has some work to go on optimizations. If _least8
and _fast8
take up more space than
So, after extending this a bit, my original conclusion about the fast_ types not being fully optimized with arm-gcc were wrong. It’s more that, on AVR, your “don’t care” counters should be unsigned for smaller size, while on STM32, they should be signed (Though I still think it’s dodgy that int_least8_t resulted in bigger code than int_fast8_t) Also, even if signed is better in the best case, the wrong signed is also the worst case. Awesome.
Huh. I hadn’t considered going through and optimizing for throwaway variables, but having just done so (without testing resulting code accuracy, admittedly), it saves my ram-strapped project quite a bit of memory.
Now to consider the changelog to make sure I haven’t introduced any regressions. :)