2018-01-06 08:38 AM
I'm still new to the Cortex M architecture, but I was wondering which is the most performing data type for integers smaller than 256 if space is abundant? Is it uint8_t, uint16_t, or uint32_t, or are they all the same?
Solved! Go to Solution.
2018-01-06 09:24 AM
Depends what you're doing with the data, manipulating it as 32-bit is generally the most efficient, ie using 8-bit or 16-bit isn't faster, and might require masking or shifting. The compiler's default 'int' size is 32-bit, and you should use this for loop iterators rather than the smallest thing you can fit it in.
If you have large tables/arrays of constants use the 8, 16 or 32-bit form the data fits into.
In assembler immediate loads have a format that goes beyond 8-bit (8-bit pattern shifted across 16 positions), things that can't be represented with the scheme are placed in a literal pool usually at the end of the function, and a PC relative load. The assembler/compiler can choose how to represent values in the most efficient fashion.
2018-01-06 09:24 AM
Depends what you're doing with the data, manipulating it as 32-bit is generally the most efficient, ie using 8-bit or 16-bit isn't faster, and might require masking or shifting. The compiler's default 'int' size is 32-bit, and you should use this for loop iterators rather than the smallest thing you can fit it in.
If you have large tables/arrays of constants use the 8, 16 or 32-bit form the data fits into.
In assembler immediate loads have a format that goes beyond 8-bit (8-bit pattern shifted across 16 positions), things that can't be represented with the scheme are placed in a literal pool usually at the end of the function, and a PC relative load. The assembler/compiler can choose how to represent values in the most efficient fashion.
2018-01-06 09:47 AM
Yes, I was referring to loop iterators, global flags, counters, function parameters, constants, and such things. I take it now that I should use uint32_t for everything for best performance, unless space matters.
2018-01-06 11:22 AM
The registers are 32-bit, the compiler will try to keep everything in registers as long as possible. The first four parameters to a function are passed in registers. So int32_t or uint32_t would be optimal. Using int or unsigned tends to be the most portable.
2018-01-07 05:26 AM
I like uint<n>_t, because you know exactly how large it is. You're right about int being more portable, but only if you're staying within the bounds of the smallest int you're possibly porting to.
2018-01-07 03:22 PM
Such a type is defined in the same stdint.h file, where all the int_8/16/32_t are defined.
It's name is int_fast8_t. Or u
int_fast8_t for unsigned.
-- pa
2018-01-08 11:38 AM
,
,
Interesting. , I looked at the definition:
♯ ifdef __INT_FAST8_TYPE__
,
typedef __INT_FAST8_TYPE__ int_fast8_t,,
typedef __UINT_FAST8_TYPE__ uint_fast8_t,,
♯ define __int_fast8_t_defined 1,
♯ elif __STDINT_EXP(INT_MAX) >,= 0x7f,
typedef signed int int_fast8_t,,
typedef unsigned int uint_fast8_t,,
♯ define __int_fast8_t_defined 1,
♯ endifI can understand the second case, where uint_fast8_t is just an alias for unsigned int (and without bounds check, it seems). But what does the first case mean? What is __INT_FAST8_TYPE__, and is it set for STM32?
2018-01-08 11:51 AM
One could benchmark, but I suspect it is about as 'fast' in performance terms as painting a line down the center of your car.
2018-01-08 11:58 AM
Well said. :)