Date: Thu, 14 Nov 2019 20:11:40 +0100
Am 14.11.19 um 16:42 schrieb Thiago Macieira via Std-Discussion:
> On Wednesday, 13 November 2019 22:29:30 PST Wilhelm Meier via Std-Discussion
> wrote:
>> The point is to use
>>
>> std::array<A, 5> a;
>>
>> auto x{a.size()}; // uint8_t
>>
>> or
>>
>> std::array<A, 5>::size_type y{}; // uint8_t
>
> Why would you want that?
Why not? Why should the type bigger than neccessary?
> Don't answer "microcontrollers" and "performance", since uint8_t will get
> promoted to int when used and return types are returned in register-sized
> chunks.
Consider this very simple example:
#include <limits>
#include <array>
std::array<uint8_t, 10> a {1, 2, 3};
volatile uint8_t r;
int main() {
for(decltype(a)::size_type i{0}; i < a.size(); ++i) {
r; // prevent the loop from being optimized away
}
for(uint16_t i{0}; i < a.size(); ++i) {
r; // dito
}
}
The first loop is with 1-Byte unsigned arithmetic and the second loop is
with 2-byte unsigned arithmetic (g++ -Os for AVR) as show below:
000000de <main>:
de: 8a e0 ldi r24, 0x0A ; 10
e0: 90 91 0a 28 lds r25, 0x280A ; 0x80280a <__data_end>
e4: 81 50 subi r24, 0x01 ; 1
e6: e1 f7 brne .-8 ; 0xe0 <main+0x2>
e8: 8a e0 ldi r24, 0x0A ; 10
ea: 90 e0 ldi r25, 0x00 ; 0
ec: 20 91 0a 28 lds r18, 0x280A ; 0x80280a <__data_end>
f0: 01 97 sbiw r24, 0x01 ; 1
f2: e1 f7 brne .-8 ; 0xec <main+0xe>
f4: 90 e0 ldi r25, 0x00 ; 0
f6: 80 e0 ldi r24, 0x00 ; 0
f8: 08 95 ret
>
>> In highly templated code the size_type "propagates" through the
>> templates and produces optimal code by choosing the "right" type in all
>> places.
>
> Using a register-sized type is "highly optimised".
In microcontroller-aplications I want to choose the type as small as
possible and as big as neccessary to give the compiler the best
information to optimize so code. And in my experience this is extremely
valuable.
> On Wednesday, 13 November 2019 22:29:30 PST Wilhelm Meier via Std-Discussion
> wrote:
>> The point is to use
>>
>> std::array<A, 5> a;
>>
>> auto x{a.size()}; // uint8_t
>>
>> or
>>
>> std::array<A, 5>::size_type y{}; // uint8_t
>
> Why would you want that?
Why not? Why should the type bigger than neccessary?
> Don't answer "microcontrollers" and "performance", since uint8_t will get
> promoted to int when used and return types are returned in register-sized
> chunks.
Consider this very simple example:
#include <limits>
#include <array>
std::array<uint8_t, 10> a {1, 2, 3};
volatile uint8_t r;
int main() {
for(decltype(a)::size_type i{0}; i < a.size(); ++i) {
r; // prevent the loop from being optimized away
}
for(uint16_t i{0}; i < a.size(); ++i) {
r; // dito
}
}
The first loop is with 1-Byte unsigned arithmetic and the second loop is
with 2-byte unsigned arithmetic (g++ -Os for AVR) as show below:
000000de <main>:
de: 8a e0 ldi r24, 0x0A ; 10
e0: 90 91 0a 28 lds r25, 0x280A ; 0x80280a <__data_end>
e4: 81 50 subi r24, 0x01 ; 1
e6: e1 f7 brne .-8 ; 0xe0 <main+0x2>
e8: 8a e0 ldi r24, 0x0A ; 10
ea: 90 e0 ldi r25, 0x00 ; 0
ec: 20 91 0a 28 lds r18, 0x280A ; 0x80280a <__data_end>
f0: 01 97 sbiw r24, 0x01 ; 1
f2: e1 f7 brne .-8 ; 0xec <main+0xe>
f4: 90 e0 ldi r25, 0x00 ; 0
f6: 80 e0 ldi r24, 0x00 ; 0
f8: 08 95 ret
>
>> In highly templated code the size_type "propagates" through the
>> templates and produces optimal code by choosing the "right" type in all
>> places.
>
> Using a register-sized type is "highly optimised".
In microcontroller-aplications I want to choose the type as small as
possible and as big as neccessary to give the compiler the best
information to optimize so code. And in my experience this is extremely
valuable.
Received on 2019-11-14 13:14:09