Forum: Compiler & IDEs WinAVR auch ohne Union optimierter Code möglich?


von Ingo S. (ingo-s)


Lesenswert?

Hi,

Beispiel:

uint16_t my_int;
uint8_t  my_byte;

   my_int |= my_byte;

Kann man auch ohne Union verhindern, das der Compiler unnötiger Weise 
das high-byte von my_int mit 0 verodert?

Gruß Ingo

von Karl H. (kbuchegg)


Lesenswert?

Ingo Stahl schrieb:
> Hi,
>
> Beispiel:
>
> uint16_t my_int;
> uint8_t  my_byte;
>
>    my_int |= my_byte;
>
> Kann man auch ohne Union verhindern, das der Compiler unnötiger Weise
> das high-byte von my_int mit 0 verodert?

ungetestet

  *(uint8_t*)&my_int |= my_byte;

von Ingo S. (ingo-s)


Lesenswert?

Hi,

Karl heinz Buchegger schrieb:
>
> ungetestet
>
>   *(uint8_t*)&my_int |= my_byte;

es funktioniert schon in diese Richtung, nur noch eine Veroderung.

Da in meinem Falle noch etwas drum herum ist, wird der Gewinn an anderer 
Stelle wieder zunichte gemacht.
Vielen Dank für den Tipp, kann man sicherlich ab und zu mal gebrauchen.

Gruß Ingo

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:

>   *(uint8_t*)&my_int |= my_byte;

Von solchen Hacks würde ich dringend abraten. Type Punning kann 
einerseits zu unerwünschten Optimierungen führen und ist andererseits 
alles andere als hübsch.

@Ingo

Wenn du mit den 3-4 überflüssigen Ticks absolut nicht leben kannst: 
Verwende (Inline)-Assembler, nur der gibt dir garantiert bestimmte 
asm-Sequenzen.
Zudem ein Bugreport für die neueste GCC-Version (4.5.2 bzw. 4.6.0) 
machen, damit diese Optimierung vielleicht irgendwann Teil von avr-gcc 
wird.

Innerhalb von avr-gcc ist das Problem, daß es keinen Königsweg betreffs 
Subreg-Lowering gibt. Dieses geschieht in Pass .149r.subreg1 und 
.182r.subreg2 (in den Dumps mit -da)

Je nach Kontext ist es manchmal günstiger, dieses Lowering zu machen 
(also breite Variablen in 8-Bit-Stücke aufzuspalten), oder aber eine 
Variable in einem Stück zu belassen, so daß nachvollziehbar bleibt, was 
mit ihr geschieht: Ein Haufen von 8-Bit-Fragmenten ist eben nicht immer 
hilfreich...

Die Subreg-Lowering-Passes können mit -f[no-]split-wide-types 
aktiviert/deaktiviert werden, allerdings wird der Schalter nicht im 
avr-Backend berücksichtigt, und je nach Verschalterung sieht ein Backend 
andere Pattern und ist nicht auf deren Verarbeitung/Optimierung 
vorbereitet -- zumindest ist's im avr-Backend so.

von Rolf M. (rmagnus)


Lesenswert?

1
    my_int = (uint8_t)my_int | my_byte;

von ... (Gast)


Lesenswert?

Nö, so gehts nicht.
Das obere Byte bleibt nicht erhalten und wird immer 0.

von Rolf M. (rmagnus)


Lesenswert?

Ups, das stimmt natürlich.

von Ingo S. (ingo-s)


Lesenswert?

@Johann
Mir ging es eher um den Flash-Speicher, bin mal wieder kurz vor der 4K 
Grenze. Aber was solls, mit Union's geht das ja sauber. Ich muss nur 
halt den Code auf die Unions umbauen.

@Rolf
> my_int = (uint8_t)my_int | my_byte;
Den Versuch habe ich hinter mir  - und wech ist der Balkon ääh, das 
highByte. Der Compiler macht genau das was man ihm sagt ;-)

Gruß Ingo

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.