expertenaustausch > comp.lang.* > comp.lang.c

Thomas Koenig (25.04.2020, 16:49)
.... ist schon ziemlich eindrucksvoll. Mikroptimierungen kann man
sich mittlerweile ziemlich gut sparen.

Ein Beispiel:

void compare (int a, int *b)
{
if (a == 0 || a == 4)
*b = 1;
}

Da könnte einem ja der Gedanke kommen, mann könnte mal maskieren und
prüfen und so... Und was machen gcc und clang?

gcc -O3:

andl $-5, %edi
jne .L1
movl $1, (%rsi)
..L1:
ret

clang -O3:

orl $4, %edi
cmpl $4, %edi
jne .LBB0_2
# %bb.1:
movl $1, (%rsi)
..LBB0_2:
retq

Genau umgekehrt, aber gleich schnell.

Man was anderes. Wie wir alle wissen, sind Divisionen aufwändig und
teuer. Was liefern uns die Compiler denn bei

void div5 (int a, int *b, int *c)
{
*b = a/5;
*c = a%5;
}

ab?

gcc -O3:

movslq %edi, %rax
movl %edi, %ecx
imulq $1717986919, %rax, %rax
sarl $31, %ecx
sarq $33, %rax
subl %ecx, %eax
movl %eax, (%rsi)
leal (%rax,%rax,4), %eax
subl %eax, %edi
movl %edi, (%rdx)
ret

clang -O3:

movslq %edi, %rax
imulq $1717986919, %rax, %rcx # imm = 0x66666667
movq %rcx, %rdi
shrq $63, %rdi
sarq $33, %rcx
addl %edi, %ecx
movl %ecx, (%rsi)
leal (%rcx,%rcx,4), %ecx
subl %ecx, %eax
movl %eax, (%rdx)
retq

Beim ersten Draufschauen erscheint der Algorithmus ein bisschen
wie schwarze Magie (man findet ihn aber). Und statt dass jeder
Programmiere sich die Literatur sucht und dann überlegt, wie
er das denn z.B. in C hinkriegen würde, hat sich mal vor Jahren
jemand hingesetzt und den Algorithmus in die Compiler eingebaut,
so dass jetzt jeder davon profitieren kann.
Rainer Weikusat (01.05.2020, 21:56)
Thomas Koenig <tkoenig> writes:
[..]
> .LBB0_2:
> retq
> Genau umgekehrt, aber gleich schnell.


Ein nuetzliches Program, in dem diese Maschinencode-Miniaturverwirrung
einen anderen, relevanten Unterschied bewirkt, ausser das sich jemand zu
Debugging-Zwecken den Kopf darueber zerbrechen muss, wuerde ich gerne
mal sehen ...
Thomas Koenig (01.05.2020, 23:52)
On 2020-05-01, Rainer Weikusat <rweikusat> wrote:

> Ein nuetzliches Program, in dem diese Maschinencode-Miniaturverwirrung
> einen anderen, relevanten Unterschied bewirkt, ausser das sich jemand zu
> Debugging-Zwecken den Kopf darueber zerbrechen muss, wuerde ich gerne
> mal sehen ...


Zunächst mal: Wer sich Assembler seiner C-Programme anschaut
und dadurch zu einer anderen Reaktion als "Ach so machen die das,
das ist moderat clever" veranlasst wird, hat noch viel zu lernen :-)
(Wobei der gcc das noch ein bisschen besser macht - wäre evtl.
ein Bug Report bei clang wert).

Der Punkt ist ein aber ein bisschen ein anderer: Das ist eine
Mikrooptimierung, die ein bisschen Platz (Cache...) und ein bisschen
Zeit spart. Beides könnte ggf. relevant werden, in vielen Fällen
wohl nicht.

Nur: Jeder Programmierer macht das damit automatisch richtig,
er muss sich um solche Mikrooptimierungen keine Gedanken
mehr machen, sie passieren einfach, weil das jemand mal
vor Jahren grundsätzlich gelöst hat.
Bonita Montero (02.05.2020, 13:31)
> Ein nuetzliches Program, in dem diese Maschinencode-Miniaturverwirrung
> einen anderen, relevanten Unterschied bewirkt, ausser das sich jemand zu
> Debugging-Zwecken den Kopf darueber zerbrechen muss, wuerde ich gerne
> mal sehen ...

Ich dagegen würde gern mal einen einzigen, nützlichen, relevanten,
unverschworbelten, geraden deutschen Satz von dir sehen, der einen anderen
Unterschied bewirkt, "ausser das sich jemand" über deine Sprach-Verwirrtheit
den Kopf zerbrechen muss.
Bonita Montero (02.05.2020, 16:37)
> Ich dagegen würde gern mal einen einzigen, nützlichen, relevanten,
> unverschworbelten, geraden deutschen Satz von dir sehen, der einen anderen
> Unterschied bewirkt, "ausser das sich jemand" über deine
> Sprach-Verwirrtheit
> den Kopf zerbrechen muss.


.... aber obiges ist nicht von mir.
Rainer Weikusat (02.05.2020, 18:04)
Thomas Koenig <tkoenig> writes:
> On 2020-05-01, Rainer Weikusat <rweikusat> wrote:
> Zunächst mal: Wer sich Assembler seiner C-Programme anschaut
> und dadurch zu einer anderen Reaktion als "Ach so machen die das,
> das ist moderat clever" veranlasst wird, hat noch viel zu lernen :-)


Da liegst Du leider falsch: Gelegentlich mag man das aus Neugierde
machen. Aber der Hauptgrund ist, dass man eine von diesen huebschen
Dateien names "core" gefunden hat und feststellen muss, was da passiert
ist und was man dagegen tun kann.

[...]

> Der Punkt ist ein aber ein bisschen ein anderer: Das ist eine
> Mikrooptimierung, die ein bisschen Platz (Cache...) und ein bisschen
> Zeit spart.


Das ist eine Code-Verkomplizierung, die bestenfalls niemandem
auffaellt. Ob das jetzt in einem gegebenen Fall schneller, langsamer
oder im selben Tempo, wie irgendwelcher funktional gleichwertige Code
ablaeuft, ist unbekannt.
Rainer Weikusat (02.05.2020, 18:05)
Bonita Montero <Bonita.Montero> writes:
> Ich dagegen würde gern mal einen einzigen, nützlichen, relevanten,
> unverschworbelten, geraden deutschen Satz von dir sehen, der einen anderen
> Unterschied bewirkt, "ausser das sich jemand" über deine Sprach-Verwirrtheit
> den Kopf zerbrechen muss.


Deine Unfaegigkeit, geschriebenes Deutsch zu verstehen und deine
Angewohnheit, dass anderen vorzuwerfen, gehoeren beide nicht hier her.
Bonita Montero (02.05.2020, 18:13)
> Deine Unfaegigkeit, geschriebenes Deutsch zu verstehen und deine
> Angewohnheit, dass anderen vorzuwerfen, gehoeren beide nicht hier
> her.


Kannst Du Idiot mal das Posting lesen was ich wirklich geschrieben
habe bevor Du voreilig auf ein vermeintliches von mir antwortest ?
Matthias Andree (02.05.2020, 18:59)
Am 02.05.20 um 16:37 schrieb Bonita Montero:
> ... aber obiges ist nicht von mir.


wenn's wem hilft:

> Path: uni-berlin.de!fu-berlin.de!news.swapon.de!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail


vs.
Thomas Koenig (02.05.2020, 20:12)
Rainer Weikusat <rweikusat> schrieb:

>> Der Punkt ist ein aber ein bisschen ein anderer: Das ist eine
>> Mikrooptimierung, die ein bisschen Platz (Cache...) und ein bisschen
>> Zeit spart.

> Das ist eine Code-Verkomplizierung,


Wieso ist das eine Verkomplizierung?

>die bestenfalls niemandem
> auffaellt. Ob das jetzt in einem gegebenen Fall schneller, langsamer
> oder im selben Tempo, wie irgendwelcher funktional gleichwertige Code
> ablaeuft, ist unbekannt.


In einer direkten Umsetzung ergäbe der Code

if (a == 0 || a == 4)
*b = 1;

zwei Vergleiche und zwei bedingte Sprünge. Das von mir gezeigte
Beispiel zeigt ein AND und einen bedingten Sprung.

Falls dir daraus nicht klar wird, was da schneller sein könnte,
dann tue ich das mal unter "rhetorischer Kunstgriff" ab.
Helmut Waitzmann (03.05.2020, 07:44)
Bonita Montero <Bonita.Montero>:

Das folgende Zitat mit den zwei Größerzeichen am Zeilenanfang
schrieb eine Person, die ebenfalls als

Bonita Montero <Bonita.Montero>

auftritt, allerdings nicht über Albasani sondern über Eternal
September am Usenet teilnimmt: 

>> Ich dagegen würde gern mal einen einzigen, nützlichen,
>> relevanten, unverschworbelten, geraden deutschen Satz von dir
>> sehen, der einen anderen Unterschied bewirkt, "ausser das sich
>> jemand" über deine Sprach-Verwirrtheit den Kopf zerbrechen
>> muss.

>... aber obiges ist nicht von mir.


Das ist auch mein Eindruck.  Ein Vergleich bringt es an den Tag: 
Wenn man den Umgangston des über Eternal September eingespeisten
Beitrags mit dem Umgangston der in dem Beitrag

Subject: Re: Was Compiler heute so treiben...
From: Bonita Montero <Bonita.Montero>
Newsgroups: de.comp.lang.c
Date: Sat, 2 May 2020 18:13:15 +0200
Message-ID: <r8k66q$4rp$1>
Path: news.albasani.net!.POSTED!not-for-mail
Organization: albasani.net

gestellten Frage «Kannst Du Idiot mal das Posting lesen was ich
wirklich geschrieben habe bevor Du voreilig auf ein vermeintliches
von mir antwortest ?»

vergleicht, fällt der wenngleich nicht perfekte, so doch
wesentlich weniger beleidigende Umgangston im über Eternal
September eingelieferten Beitrag auf. 

Deine, gerne mal beleidigenden, Beiträge jedoch kommen über
Albasani ins Usenet.  Es handelt sich also eindeutig um zwei
verschiedene Personen. 

Den Verdacht habe ich schon länger:  Du missbrauchst den Namen der
Person, die als Bonita Montero über Eternal September im Usenet
unterwegs ist, als Pseudonym, obwohl er überhaupt nicht zu dir
passt. 

Wenn du schon weiterhin pseudonym unterwegs sein willst, kann ich
dir «Malito Molesto» empfehlen.  Das passt wesentlich besser.. 

Aber das gehört nicht hierher.  Deshalb schlage ich ein

Crosspost & Followup-To: de.soc.usenet

vor. 
Thomas Koenig (03.05.2020, 10:59)
Rainer Weikusat <rweikusat> schrieb:

> Da liegst Du leider falsch: Gelegentlich mag man das aus Neugierde
> machen. Aber der Hauptgrund ist, dass man eine von diesen huebschen
> Dateien names "core" gefunden hat und feststellen muss, was da passiert
> ist und was man dagegen tun kann.


Na, da gibt es doch ganz andere Methoden. Wenn du das rausfinden
willst, dann gibt es verschiedene Möglichkeiten (sind jetzt
gcc-spezifisch):

Du kannst mit -Og übersetzen. Dann kommt z.B aus

void compare (int a, int *b)
{
if (a == 0 || a == 4)
*b = 1;
}

das hier raus:

testl %edi, %edi
sete %dl
cmpl $4, %edi
sete %al
orb %al, %dl
je .L1
movl $1, (%rsi)

Es geht aber noch ein bisschen besser. -fverbose-asm -Og (aber
_ohne_ -g) liefert dir für den Code oben

# compare.c:3: if (a == 0 || a == 4)
testl %edi, %edi # a
sete %dl #, tmp87
# compare.c:3: if (a == 0 || a == 4)
cmpl $4, %edi #, a
sete %al #, tmp88
# compare.c:3: if (a == 0 || a == 4)
orb %al, %dl # tmp88, tmp87
je .L1 #,
# compare.c:4: *b = 1;
movl $1, (%rsi) #, *b_7(D)
..L1:
# compare.c:5: }
ret

Wenn den Assembler-Code dann mit -g übersetzt, dann kann man
da wunderbar durchsteppen. Mache ich in extrem seltenen Fällen,
aber nur wenn es wirklich nötig ist :-)
Bonita Montero (03.05.2020, 17:30)
Das funktioniert aber oft nicht richtig weil es optimierter-weise
keinen linearen, also aufeinanderfolgenden, Zusammenhang zwischen
Code-Zeilen und Assembler-Output gibt.
Rainer Weikusat (03.05.2020, 21:13)
Thomas Koenig <tkoenig> writes:
> Rainer Weikusat <rweikusat> schrieb:
>>> Der Punkt ist ein aber ein bisschen ein anderer: Das ist eine
>>> Mikrooptimierung, die ein bisschen Platz (Cache...) und ein bisschen
>>> Zeit spart.

>> Das ist eine Code-Verkomplizierung,

> Wieso ist das eine Verkomplizierung?


In richtigem Code wuerde der Vergleich wohl eher so ausshen:

if (a == HAVE_ELEPHANT || a == HATE_TEABAGS)
*b = GOTCHA;

wenn da auf Maschinencode-Ebene ein gleichwertige, andere arithmetische
Operation, die von den mehr oder minder zufaelligen Zahlenwerten dieser
Konstanten abhaengt, rauskommt, muss jemand, der den erzeugten Code
verstehen will, diese "Mikrooptimierung" nach Ermitteln der Zahlenwerte
im Kopf nachvollziehen. Dazu muss man erstmal verstehen, dass bei
Zweierkomplement -5 == ~4 gilt und das die zwei Vergleiche arithemtisch
aequivalent zu

if ((a & ~4) == 0)

sind.

> In einer direkten Umsetzung ergäbe der Code
> if (a == 0 || a == 4)
> *b = 1;
> zwei Vergleiche und zwei bedingte Sprünge. Das von mir gezeigte
> Beispiel zeigt ein AND und einen bedingten Sprung.
> Falls dir daraus nicht klar wird, was da schneller sein könnte,
> dann tue ich das mal unter "rhetorischer Kunstgriff" ab.


Die zwei Vergleiche koennten jedenfalls parallell ausgefuehrt werden,
weil sie seiteneffektfrei sind und die Laufzeit des Codeabschnittes, der
dieses Fragment enthaelt, duerfe wesentlich davon abhaengen, ob der
Sprung bei einer Ausfuehrung korrekt vorhergesagt wird. Im Vergleich zu
den Kosten, die durch eine falsche Sprungvorhersage entstehen wuerden,
ist "eine Ganzzahloperation mehr oder weniger" jedenfalls Hintergrundrauschen.

Das kann schneller ablaufen. Oder eben auch nicht. Um das
herauszufinden, muesste man mit konkretem Code und realistischen
Eingabedaten entsprechende Experimente anstellen.
Rainer Weikusat (03.05.2020, 21:21)
Thomas Koenig <tkoenig> writes:
> Rainer Weikusat <rweikusat> schrieb:
> Na, da gibt es doch ganz andere Methoden. Wenn du das rausfinden
> willst, dann gibt es verschiedene Möglichkeiten (sind jetzt
> gcc-spezifisch):
> Du kannst mit -Og übersetzen.


Aber nicht rueckwirkend :-). Damit man mit dem core dump etwas anfangen,
muss man genau das kompilierte Programm benutzen, dessen Speicherauszug
man hat.

Ähnliche Themen