avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: odd optimization differences of shift between C andC++


From: David Brown
Subject: Re: odd optimization differences of shift between C andC++
Date: Thu, 31 Dec 2020 18:50:29 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1

Yes, signed types always have such issues.  That is a big reason why I
started by saying you should /never/ be using "char" for arithmetic -
always use int8_t or uint8_t (or int_fast8_t, uint_least8_t, etc., or
application-specific typedefs of these).  Leave "char" for holding
characters - ASCII letters and elements of an ASCII string.

On a chip like the AVR, don't use signed types for arithmetic unless you
actually need negative values, as they are less efficient in some
circumstances.

mvh.,

David


On 31/12/2020 18:18, Jochen Barth wrote:
> Thanks. Did forget to mention that *16/256 instead of >>4 does insert
> some code to add ((2^n) -1) on negative values (because /16 and >>4 is
> not the same).
> 
> So a direct optimization on shr would be better.
> 
> Kind regards, Jochen
> 
> 
> Am 30.12.20 um 12:19 schrieb David Brown:
>> Hi,
>>
>> As a general point, never use "char" like this - use either uint8_t or
>> int8_t depending on whether you want signed or unsigned.  Usually if you
>> are doing shifts, it's uint8_t you want.
>>
>> The AVR compiler has trouble with some of these kinds of expressions.  I
>> think it has something to do with the way gcc handles them (most cpus
>> have instructions for multiple shifts or rotates) combined with the
>> integer promotion.  The AVR gcc port has 16-bit int (it's the smallest
>> size allowed by C and C++), which means everything has to be done with
>> double registers, then there are peepholes and other optimisation passes
>> that try to remove the redundant code.  A lot of that is manual work
>> added to the compiler, and so there are bound to be combinations that
>> have not been included.  Each suboptimal combination has to be spotted,
>> then added to the compiler.
>>
>> The different rearrangements done earlier in the compile process can
>> also mean that the internal code passed to the backend optimiser can
>> vary substantially.  For example, with most gcc ports, you can split
>> expressions into multiple local variables without it affecting the
>> (optimised) results.  For the AVR, that does not always apply.
>>
>> This all means it is not easy to guess the source code to use to get the
>> optimal results.  These three versions all give the same code for both C
>> and C++, with shorter and faster code than 5 shifts (it has one
>> nibble-swap, one shift and one mask).
>>
>> uint8_t u;
>>
>> void fooa(void) {
>>      u = ((u & 0xe0) >> 5);
>> }
>>
>> void foob(void) {
>>      u = u / (1u << 5);
>> }
>>
>> void fooc(void) {
>>      u = (u >> 5) & 0x07;
>> }
>>
>>
>> You can also consider using the "-mint8" flag.  That breaks C
>> compatibility but it can be useful for small programs, and can often
>> result in better code.  Be very careful to stick to <stdint.h> types
>> rather than "int" and "long" if you are trying this!
>>
>> David
>>
>>
>>
>> On 29/12/2020 21:00, Jochen Barth wrote:
>>> I'm using Arduino 1.8.13 with avr-g++ (GCC) 7.3.0.
>>>
>>> char x;
>>> x >>= 5 generates asm (promoted to 16 bit signed) with 5* asr+ror;
>>> x = x * (1<<(8-5)) / 256
>>> generates 5* asr (without type promotion).
>>>
>>> Kind regards,
>>> Jochen
>>>
>>>
>>> Weddington, Eric Mon, 08 Nov 2010 04:25:48 -0800
>>>> -----Original Message-----
>>>> From:
>>>> avr-gcc-list-bounces+eric.weddington=atmel....@nongnu.org
>>>> [mailto:avr-gcc-list-bounces+eric.weddington=atmel....@nongnu.
>>>> org] On Behalf Of William "Chops" Westfield
>>>> Sent: Sunday, November 07, 2010 9:58 PM
>>>> To: avr-gcc-list@nongnu.org
>>>> Subject: [avr-gcc-list] odd optimization differences of shift
>>>> between C andC++
>>>>
>>>>
>>>>
>>>> Is this expected? Is it bug-worthy ?
>>>>
>>> I would say that it's bug-worthy, as a missed optimization bug. FYI,
>>> there are
>>> more bugs with the C++ compiler for the AVR than for the C compiler.
>>> So I'm not
>>> totally surprised that this is happening.
>>>
>>> BTW, could you please subscribe to the mailing list? That way your
>>> posts do not
>>> have to be approved by hand.
>>>
>>> _______________________________________________
>>> AVR-GCC-list mailing list
>>> AVR-GCC-list@nongnu.org
>>> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>>>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]