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
|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
|int_fast8_t||1212||820|I would personally say that it looks like ARM still has some work to go on optimizations. If
_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.