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. :)