Ich arbeite an Optimierungsverfahren, die vom .Net Native Compiler durchgeführt werden. Ich habe einen Sample-Loops:Warum kompiliert .Net Native die Schleife in umgekehrter Reihenfolge?
for (int i = 0; i < 100; i++)
{
Function();
}
Und ich habe es mit india zusammengestellt. Dann zerlegte ich das Ergebnis .dll
Datei mit Maschinencode in IDA. Als Ergebnis habe ich:
(ich ein paar unnötige Linien entfernt haben, also keine Sorge, dass Adresse Linien inconsistant sind)
Ich verstehe, dass add esi, 0FFFFFFFFh
wirklich bedeutet subtract one from esi and alter Zero Flag if needed
, so Wir können zum Anfang springen, wenn die Null noch nicht erreicht ist.
Was ich nicht verstehe ist, warum hat der Compiler die Schleife reaverse?
Ich kam zu dem Schluss, dass
LOOP:
add esi, 0FFFFFFFFh
jnz LOOP
als zum Beispiel nur schneller ist
LOOP:
inc esi
cmp esi, 064h
jl LOOP
Aber ist es aus diesem Grunde wirklich und ist der Geschwindigkeitsunterschied wirklich wichtig?
ADD mit einem sofortigen Wert ist schneller als INC und Sie überspringen auch CMP ... alle diese in 3 Zeilen Code. Dann ja, Unterschied ist wirklich wichtig (sowohl in Größe und Geschwindigkeit). Stellen Sie sich vor, Sie tun dies in ~ 30000 Orten in einem realen Weltprogramm ... –
Ja, es ist schneller, und im Allgemeinen werden Optimierer jede mögliche Optimierung anwenden, die Ihren Code schneller macht, ohne die Semantik Ihres Programms zu ändern. –
In Bezug auf die umgekehrte Richtung ist vielleicht der Vergleich mit Null schneller als der Vergleich mit einem bestimmten Wert? – user5226582