Forum: Compiler & IDEs Addition oder OR


von Thomas L. (thomasblue)


Lesenswert?

Hallo zusammen,

es gibt ja Situationen, bei denen die Operationen + bzw. | das gleiche 
bewirken. Ein Beispiel wäre:

int tmp;
int array[2];

tmp = (array[0] & 0x00ff) + ((array[1] << 8) & 0xff00);
tmp = (array[0] & 0x00ff) | ((array[1] << 8) & 0xff00);

Ist es richtig, dass das "verodern" die schnellere Variante ist?

Viele Grüße

von (prx) A. K. (prx)


Lesenswert?

Thomas L. schrieb:

> Ist es richtig, dass das "verodern" die schnellere Variante ist?

In dieser Allgemeinheit formuliert: nein.

Das hängt davon ab, ob der Compiler die Varianten verschieden optimiert, 
weil er erkennt, dass es eine Byterekombination ist. Den meisten 
Maschinen ist egal ob sie addiereren oder verodern müssen.

von Unselbstständig (Gast)


Lesenswert?

Thomas L. schrieb:
> Ist es richtig, dass das "verodern" die schnellere Variante ist?

Beides programmieren und ins ASM schauen, was der Compiler daraus 
gemacht hat.

von Thomas L. (thomasblue)


Lesenswert?

Ok danke. Ich dachte, dass es vielleicht eine allgemeingültige Aussage 
dazu gibt. Der einzige Unterschied ist die Operation die er benutzt 
(entsprechend add oder or, mit Visual Studio angeschaut)

von Uwe (Gast)


Lesenswert?

Mußt du dir die spec der CPU angucken. z.B. könnte es sein das der add 
Befehl das Negative Flag im condition code register setzt und die oder 
Operation nicht.

von Thomas L. (thomasblue)


Lesenswert?

Ah ok, das ist noch mal ein Hinweis. Danke!

von Peter D. (peda)


Lesenswert?

Beim AVR-GCC ist mir aufgefallen, daß er OR nicht mag. Er erzeugt dann 
fast immer schlechteren Code.
Eigentlich sollte der Code ja kleiner sein, da er nur ein Byte ändern 
muß, es kann ja keinen Übertrag geben.


Peter

von Rene H. (Gast)


Lesenswert?

Ich kann bestätigen das mit einem Sun Solaris Sparc Compiler "verodern" 
schneller ist.
Wie es sich mit gcc und/oder anderen Prozessoren verhält weiss ich 
nicht.

von Oliver (Gast)


Lesenswert?

Ganz grundsätzlich und überhaupt gilt auch hier:

"don't optimize something that is not the problem"

WENN diese einzelne Zeile absolut zeitkritisch ist UND das auch durch 
seriöses Profiling im Einzelfall nachgewiesen wurde, UND man gewillt 
ist, das auch sorgfältig und nachvollziehbar zu dokumenieren, DANN kann 
man über solche Tricks nachdenken.

Ansonsten sollte man les- und wartbarkeit grundsätzlich bevorzugen. Wenn 
also zwei Integerwerte zu addieren sind, schreibt man "+", wenn zwei 
Bitmasken zu ver-odern sind, emtsprehcend "|". Ob beides im Einzelfall 
zum gleichen Ergebnis führt, ist egal.

Oliver

von Mark B. (markbrandis)


Lesenswert?

Oliver schrieb:
> Ansonsten sollte man les- und wartbarkeit grundsätzlich bevorzugen.

Quoted for truth.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Peter Dannegger schrieb:
> Beim AVR-GCC ist mir aufgefallen, daß er OR nicht mag. Er erzeugt dann
> fast immer schlechteren Code.

Bei neueren Compiler-Versionen ist es in Beispielen wie dem oben
genannten eher andersherum.

Deswegen bringt es tatsächlich nicht viel, an solchen Stellen optimieren
zu wollen. Für mich ist die Oder-Variante die logisch etwas sinnvollere.
Außerdem kann man bei ihr auf die vielen hässlichen Klammern verzichten.

von Peter D. (peda)


Lesenswert?

Yalu X. schrieb:
> Außerdem kann man bei ihr auf die vielen hässlichen Klammern verzichten.

Seit wann geht das denn?

Der WINAVR meckert es jedenfalls an:
1
4.3.3
2
or.c: In function 'test2':
3
or.c:7: warning: suggest parentheses around arithmetic in operand of |


Peter

von (prx) A. K. (prx)


Lesenswert?

Er sagt damit ja nur, dass manche Anwender die Prioritäten nicht im Kopf 
haben und man denen zuliebe Klammern setzen sollte.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Peter Dannegger schrieb:
>> Außerdem kann man bei ihr auf die vielen hässlichen Klammern verzichten.
>
> Seit wann geht das denn?
>
> Der WINAVR meckert es jedenfalls an:4.3.3
> or.c: In function 'test2':
> or.c:7: warning: suggest parentheses around arithmetic in operand of |

Manchmal übertreibt er es auch ein wenig. Abhilfe:

  -Wno-parentheses

;-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Beim AVR-GCC ist mir aufgefallen, daß er OR nicht mag.

Siehe http://gcc.gnu.org/PR41076

Konstruktive Vorschläge sind willkommen und können für avr-gcc 4.8 
umgesetzt werden.

von Mark B. (markbrandis)


Lesenswert?

A. K. schrieb:
> Er sagt damit ja nur, dass manche Anwender die Prioritäten nicht im Kopf
> haben und man denen zuliebe Klammern setzen sollte.

Seit wann sehen Anwender einer Software den Sourcecode? (mit Ausnahme 
der Ausnahmen)

Gute Programmierer setzen gerade so viele Klammern, wie eben nötig sind, 
damit der Compiler keine Warnungen ausgibt.

Und wer Klammern hässlich findet, der hat noch nie LISP programmiert - 
oder schon zu oft ;-)

von (prx) A. K. (prx)


Lesenswert?

Mark Brandis schrieb:

 Seit wann sehen Anwender einer Software den Sourcecode?

Viele. Die Anwender des Compilers.

von Mark B. (markbrandis)


Lesenswert?

A. K. schrieb:
> Viele. Die Anwender des Compilers.

Anwender eines Compilers heißen hier "Entwickler". 8-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mark Brandis schrieb:
> Anwender eines Compilers heißen hier "Entwickler". 8-)

Und wie heißen dort dann die Entwickler des Compilers? Götter? ;-)

von Thomas L. (thomasblue)


Lesenswert?

Grundsätzlich bin ich auch für lesbareren Code (und um Klarheit zu 
schaffen auch eher mehr Klammern als unbedingt nötig).
Von daher stimme ich zu, dass Integerwerte per "+" zu addieren sind und 
Bitmasken per "|" zu ver-odern sind.

Nur hätte es ja sein können, dass man eine grundsätzliche Aussage 
darüber hätte treffen können, was schneller ist. Da das aber so stark 
von Compiler abhängig ist, muss es wenn nötig jeweils im Einzelfall 
entscheiden.

von Oliver (Gast)


Lesenswert?

Thomas L. schrieb:
> Nur hätte es ja sein können, dass man eine grundsätzliche Aussage
> darüber hätte treffen können,

Ausser in pathologischen Grenzfällen ist es doch prinzipiell nicht 
sinnvoll, überhaupt über "Optimierungen" auf diesem Level nachzudenken. 
Das führt ausser zu miserablen Code zu gar nichts. In 100% aller Fälle 
spielt ein eventueller Auführunsggeschwindigkeitsunterschied keine 
Rolle. Dazu kommt, daß Compilerbauer nicht dumm sind - manch ein 
Compiler optimiert so etwas.

Wenn es in einer zeitkritischen Routine tatsächlich auf jeden einzlenen 
Prozessorzyklsu ankommt, geht eine Optimierung sowieso nicht ohne Blick 
ins erzeugte Compilat, und dann beantworten sich solche Fragen von 
alleine.

Oliver

von abc (Gast)


Lesenswert?

Bei einem guten Compiler sollte das doch egal sein, weil er die 
Optimierung selbst vornimmt. Der C-Programmierer sollte es so machen, 
wie es für einen Menschen am besten lesbar ist.

Genauso sollte doch egal sein ob ich
i++;
oder i=i+1;
oder i+=1;
schreibe
In jedem Falle sollte der Compiler ein inc daraus machen, sofern es die 
verwendeten Datentypen zulassen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Mark Brandis schrieb:
> Und wer Klammern hässlich findet, der hat noch nie LISP programmiert -
> oder schon zu oft ;-)

LISP: Lots of Irritating Single Parentheses

;-)

von Marwin (Gast)


Lesenswert?

Mark Brandis schrieb:

> Gute Programmierer setzen gerade so viele Klammern, wie eben nötig sind,
> damit der Compiler keine Warnungen ausgibt.

Nein, mit sowas bruesten sich nur Programmierer, die sich fuer gut 
halten.

Wirklich gute Programmierer schreiben Code der eindeutig wiedergibt, was 
sie machen wollen - auch wenn man nicht alle Compiler-Regeln auswendig 
weiss. Denn man weiss nie, ob der naechste Programmierer genauso gut ist 
wie man selbst, oder ob man in 5 Jahren noch genauso gut alle Regeln 
parat hat oder, was noch viel wichtiger ist: Ob man wirklich selbst so 
gut ist, wie man glaubt.

von Peter D. (peda)


Lesenswert?

Marwin schrieb:
> Wirklich gute Programmierer schreiben Code der eindeutig wiedergibt, was
> sie machen wollen - auch wenn man nicht alle Compiler-Regeln auswendig
> weiss.

Daß OR nachrangig ist, ist doch klar.
Ich programmiere auch CPLDs und da hat noch nie jemand unnütze Klammern 
gesetzt.
Ein CPLD hat eine AND/OR-Matrix, d.h. erst erfolgt die AND-Verknüpfung 
und dann das OR.
Es ist nur üblich, daß die OR-Terme auf die nächste Zeile kommen, da 
deren Anzahl begrenzt ist und man so besser die Auslastung erkennt.
Ein GAL22V10 hat z.B. Macrozellen mit 8 .. 16 OR-Termen.


Peter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Neben PLUS und OR gibt's ja noch XOR :-)

tmp = (array[0] & 0x00ff) ^ ((array[1] << 8) & 0xff00);

Was soll array[] eigentlich sein?

Ein byte-Array? Word-Array? Double-Array? Und tmp?

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.