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

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

Re: [avr-gcc-list] suggestion


From: David Brown
Subject: Re: [avr-gcc-list] suggestion
Date: Wed, 5 Jul 2006 15:20:09 +0200

Just a few points:

The "sbi" macro is old and deprecated - if you use "PORTC |= mask" with only
one bit set, the compiler will automatically generate the optimal instuction
(such as sbi).  In fact, the "sbi" macro is defined specifically as:
    #define sbi(port, bit) (port) |= (1 << (bit))
in the header "deprecated.h"


Secondly, as someone else said, setting two bits at the same time, or
setting them as two individual sbi instructions, does not have the same
effect, and might change the correctness of programs.


Finally, it is strange that such a small change has such a large
(percentwise) effect on the size of your program.  I'd guess you'd get far
bigger improvements by factoring out some common code into functions, and
other similar changes.  Other things that can use up a lot of code are if
you've accidently included floating point libraries, or used printf or other
"big" library functions (look at your map files to see what is taking the
space).  Also make sure you are compiling with "-Os" optimisation.

If you really want to get the smallest possible space, I expect version 4.1
of the compiler with "whole-program" and "combine" optimisations will save
more space.

mvh.,

David



> I'm a total newbie to avr-gcc and just compiled a first program. It merely
> fits the program memory so I've started to optimize..
>
> In my code there lots of places where 1-2-3 bits are flipped in I/O port:
>
>
> #define set_line_in_lcd_control_port(pin) sbi(PORTC, (pin))
> #define set_lines_in_lcd_control_port(mask) PORTC |= (mask)
> ..
> set_lines_in_lcd_control_port (_BV(LCD_CS1) | _BV(LCD_CS2));
> ..
> set_line_in_lcd_control_port(LCD_E);
>
> so, when 1 bit is toggled set_line_in_lcd_control_port is used, if more
> - bits are set using a mask. This second #define compiles into
>
> set_lines_in_lcd_control_port (_BV(LCD_CS1) | _BV(LCD_CS2));
> 2d40: 85 b3       in r24, 0x15 ; 21
> 2d42: 88 61       ori r24, 0x18 ; 24
> 2d44: 85 bb       out 0x15, r24 ; 21
>
>
> whereas first into
>
> set_line_in_lcd_control_port(LCD_E);
> 2d36: af 9a       sbi 0x15, 7 ; 21
>
>
> that is, just one word to toggle one bit and 3 words to toggle 2+ bits.
>
> My suggestion is to optimize the case when 2 bits are set into 2 sbi
> commands, and when 2 bits are cleared into 2 cbi commands. It's quite
> easy to count number of 1s or 0s in the mask - and if there are exacly
> 2, apply this optimization.
>
> I was able to save ~100 bytes and fit my program into 4K, just by
optimizing
> these often used bit-tweaking places in my program.
>
> If someone would have time to implement this kind of optimization for
> I/O ports, that would be really great! I've never dealt with compilers
> and just don't know how to do that..
>
>
>
>
>
>
>
> _______________________________________________
> AVR-GCC-list mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>





reply via email to

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