www.mikrocontroller.net

Forum: Compiler & IDEs GCC-Interna: Optimierung von Bitmasken


Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wieder so eine Sache, die sich mir nicht erschließt:
MODULATE_A ist hier ein Bitfeld von einem Bit Breite, das auf ein SFR 
außerhalb des I/O-Bereiches zeigt (hier TIMSK, Details im Anhang).

Dann nehme man folgende Schnippsel her:
/* Variante A */
if (phase_a > 0)
  MODULATE_A = 1;
else
  MODULATE_A = 0;
und
/* Variante B */
MODULATE_A = (phase_a > 0);

Da fällt auf (avr-gcc 4.5.1, -Os): Bei Variante A werden schlicht und 
ergreifend zwei Masken erzeugt und mit ori und andi verarbeitet:
 520:  49 b7         in  r20, 0x39  ; 57
 522:  88 23         and  r24, r24
 524:  11 f0         breq  .+4        ; 0x52a <__stack+0xcb>
 526:  48 60         ori  r20, 0x08  ; 8
 528:  01 c0         rjmp  .+2        ; 0x52c <__stack+0xcd>
 52a:  47 7f         andi  r20, 0xF7  ; 247
 52c:  49 bf         out  0x39, r20  ; 57

Wohingegen der GCC sich bei zweiter Variante mit obskuren Operationen 
abquält:
 4fe:  41 e0         ldi  r20, 0x01  ; 1
 500:  88 23         and  r24, r24
 502:  09 f4         brne  .+2        ; 0x506 <__stack+0xa7>
 504:  40 e0         ldi  r20, 0x00  ; 0
 506:  42 95         swap  r20
 508:  40 7f         andi  r20, 0xF0  ; 240
 50a:  89 b7         in  r24, 0x39  ; 57
 50c:  8f 7e         andi  r24, 0xEF  ; 239
 50e:  84 2b         or  r24, r20
 510:  89 bf         out  0x39, r24  ; 57

Woher kommt das denn? Je nachdem, welches Bit gemeint ist (hier OCIE1A) 
schiebt und rotiert und addiert er sich einen zurecht und macht 
eigentlich alles, nur nicht das schicke, schlanke ori/andi von zuvor.

Danke und Gruß,
Sven

Autor: Sven P. (haku) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja, die Sache mit dem Anhang...

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wär's mit einem compilierbaren Beispiel?
Welche Optionen sind gesetzt?
Was ist phase_a?
Wieso IN und OUT wenn das auf ein "SFR außerhalb des I/O-Bereiches 
zeigt"?
Welcher µC?

Übersetze mit -fdump-tree-all -da (erzeugt ca. 150 temporäre Dateien je 
nach Verschalterung) und du siehst zumindest den Pass wo es passert 
(bzw. nicht passiert).

AFAIK implementiert das avr-Backend keine Pattern für Vergleiche, also 
keine Pattern "scond" wie in den Internals [1] beschrieben

[1] 
http://gcc.gnu.org/onlinedocs/gccint/Standard-Name...

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:

> "scond"

Die heissen inzwischen cstoremode4

Autor: Sven P. (haku) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Wie wär's mit einem compilierbaren Beispiel?
Auha, sorry. Ist wieder bei der Vorschau abhanden gekommen :-(

> Welche Optionen sind gesetzt?
Übersetzung:
$ avr-gcc -Wall -Wextra -mmcu=atmega8 -Os -g -DF_CPU=16000000UL --std=c99 -ffunction-sections -fdata-sections -o avrtest.o -c avrtest.c

Bindung:
$ avr-gcc -mmcu=atmega8 -g -Wl,--gc-sections -o object avrtest.o

Listing:
$ avr-objdump -h -S -d object > list

Version:
$ avr-gcc --version
avr-gcc (GCC) 4.5.1




> Wieso IN und OUT wenn das auf ein "SFR außerhalb des I/O-Bereiches
> zeigt"?
Korrigiere, außerhalb des bit-adressierbaren I/O-Bereiches. Das sollte 
zum Ausdruck bringen, dass sbi/cbi nicht mehr funktionieren.

> Übersetze mit -fdump-tree-all -da (erzeugt ca. 150 temporäre Dateien je
> nach Verschalterung) und du siehst zumindest den Pass wo es passert
> (bzw. nicht passiert).
>
> AFAIK implementiert das avr-Backend keine Pattern für Vergleiche, also
> keine Pattern "scond" wie in den Internals [1] beschrieben
Tatsächlich, interessant, mal hineinzuschauen.
Bereits im dritten Schritt (gimple) zerlegt er die erste Variante in 
einen bedingten Sprung mit ori/andi, wohingegen sich die zweite Variante 
bis zum Schluss als Ausdruck hält und dann wohl mehr oder weniger 1:1 
übersetzt wird.

Danke!

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven P. schrieb:
> Übersetzung:
> ...

Bei solchen Beispielen reicht schon compilierbar im engeren Sinne, also
$ avr-gcc -c foo.c -save-temps ...

Mit save-temps werden s- und i-File nicht gelöscht. Linkfähig (main 
etc.) braucht es nicht zu sein.

avr-gcc 4.5 übersetzt die Beispiele
/* Variante A */
void foo_a (uint8_t phase_a)
{
    if (phase_a > 0)
        MODULATE_A = 1;
    else
        MODULATE_A = 0;
}

/* Variante B */
void foo_b (uint8_t phase_a)
{
    MODULATE_A = (phase_a > 0);
}

so wie hingeschrieben. In B berechnet er zunächst phase_a != 0 (phase_a 
ist unsigned), das ist 0 oder 1, und schiebt das dann an die benötigte 
Bitposition 4 (swap+andi).

Das Problem bei der Optimierung ist, daß man bei der Erzeugung des Bits 
schon was über dessen Verwendung wissen müsste (bzw. umgekehrt), um das 
zur Optimierung zu verwenden. So wäre es in Fall B günstiger, das Bit 
nicht in Position 0 zu erzeugen, sondern in Position 4. Die optimale 
Sequenz
in   r20, 0x39
cbr  r20, 4
cpse r24, __zero_reg__  ;; phase_a
sbr  r20, 4
out  0x39, r20
mit gcc zu erzeugen wäre recht viel Arbeit und würe auch Codeänderungen 
an Stellen nach sich ziehen, die scheinbar nichts mit der genannten 
Sequenz zu tun haben.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.