2010-05-13 14 views
17

Ich mache jetzt einen Assembly-Kurs, und der Typ, der unsere Hausaufgaben überprüft, ist ein sehr pedantischer Oldschool-Optimierungs-Freak. Zum Beispiel zieht er 10%, wenn er sieht:Most Efficient set to register on 1 or (-1)

mov ax, 0 

statt:

xor ax,ax 

auch wenn es nur ein einziges Mal verwendet wird.

Ich bin kein kompletter Anfänger in der Montage Programmierung, aber ich bin kein Optimierungsexperte, also brauche ich deine Hilfe in etwas (könnte eine sehr dumme Frage sein, aber ich werde trotzdem fragen): wenn ich einstellen muss ein Registerwert auf 1 oder (-1) ist es besser, zu verwenden:

mov ax, 1 

oder so etwas wie:

xor ax,ax 
inc ax 

ich wirklich eine gute Note benötigen, so versuche ich, es zu bekommen so optimiert wie möglich. (Ich muss beide Zeit und Code-Größe optimieren)

+2

die gleiche Befehlsfolge in Verwendung ** ** jeder Kontext Sie nicht optimale Geschwindigkeit geben ** oder ** Größe. Für (ein beschissenes) Beispiel, was, wenn 'cx' garantiert '1' an dem Punkt ist, an dem du 'ax' auf '1' setzen musst? Du könntest einfach 'move ax, cx'. –

Antwort

8

Eine schnelle google für 8086 instructions timings size drehte sich http://8086.tk/, die alle Zeiten und Größen für die 8086 (und mehr) Befehlssätze zu haben scheint.

Kein Zweifel, Sie könnten offizielle Intel-doco im Web mit ähnlichen Informationen finden.

für Ihre spezifische Frage:

xor ax,ax 
inc ax 

dauert 3 + 3 = 6 Taktzyklen und 2 + 1 = 3-Bytes während

mov ax,1 

4 Taktzyklen und 3 Bytes annimmt.

So ist letzteres in diesem Fall besser.


Aber Sie müssen mit Ihrem Bildungsinstitut über diesen Typ sprechen. 10% für eine einfache Sache wie diese Bettler glauben.

Sie sollten sich fragen, was Sie tun sollten, wenn Sie zwei Möglichkeiten haben, eine schnellere und eine kürzere.

Dann, nachdem sie zugegeben haben, dass es je nach dem, was Sie erreichen wollen, verschiedene Code-Möglichkeiten gibt, sagen Sie ihnen, dass das, was Sie erreichen wollen, Lesbarkeit und Wartbarkeit ist und ernsthaft nicht fliegen kann Sprung über einen verschwendeten Zyklus oder Byte hier oder dort * a.

Optimierung ist etwas, das Sie im Allgemeinen tun, wenn Sie ein Leistungsproblem haben, nachdem ein Stück Code in einem fast vollständigen Zustand ist - es ist fast immer verschwendete Mühe, wenn der Code immer noch einer nicht unwesentlichen Wahrscheinlichkeit unterliegt Veränderung.

scheint mit xor ax,ax in Bezug auf Taktzyklen und Bytes auf Augenhöhe zu sein, so vielleicht könnten Sie das nächste Mal in die Mischung werfen, um ihn etwas mehr Arbeit zu verursachen.

* a) Nein, nicht wirklich, aber es macht Spaß gelegentlich abzulassen :-)

+0

danke für die info, rate ich werde die xor inc Option verwenden – Bob

+0

Es gibt nichts das bisschen unlesbar über 'mov ax, 1'. Du müsstest auf die nächste Stufe des Asm-Coders gehen, um ähnlich komfortabel zu sein mit xor ax, axe; inc ax'. Es gibt Lesbarkeitsstufen sogar in der Montage. Ich selbst würde eine Makro 'set_1 Axt' machen, die nur zu letzterem übersetzt wurde und sowohl Lesbarkeit als auch Geschwindigkeit/Größe gewonnen hat :-) – paxdiablo

+0

@Bob, sorry Kumpel, ich habe einen Fehler gemacht, indem ich die Kosten für die 'inc ax' weggelassen habe - Es stellt sich heraus, dass die 'mov ax, 1' tatsächlich kurz und schneller (und lesbarer) ist. – paxdiablo

2

auf Ihren persönlichen Umständen abhängig, können Sie in der Lage sein, um wegzukommen mit ...

sbb ax, ax 

Das Ergebnis ist entweder 0, wenn das Übertragsflag nicht gesetzt ist, oder -1, wenn das Übertragsflag gesetzt ist.

Wenn jedoch das obige Beispiel auf Ihre Situation nicht anwendbar ist, würde ich die

xor ax, ax 
inc ax 

Methode empfehlen. Es sollte Ihren Professor für die Größe zufriedenstellen. Wenn Ihr Prozessor jedoch ein Pipelining verwendet, würde ich erwarten, dass zwischen den beiden Anweisungen eine kupplungsartige Verzögerung auftritt (ich könnte damit sehr falsch liegen). Wenn eine solche Kopplung besteht, könnte die Geschwindigkeit etwas verbessert werden, indem Sie Ihre Anweisungen leicht neu anordnen, um eine weitere Anweisung zwischen ihnen zu haben (eine, die keine Axt verwendet).

Hoffe, das hilft.

0

Ich würde mov [e]ax, 1 unter keinen Umständen verwenden. Seine Codierung ist nicht länger als die hackier xor Sequenz, und ich bin mir ziemlich sicher, dass es fast überall schneller ist. 8086 ist einfach komisch genug, um die Ausnahme zu sein, und da dieses Ding so langsam ist, würde eine solche Mikrooptimierung den größten Unterschied ausmachen. Aber wo auch immer: Die Ausführung von 2 "einfachen" Anweisungen ist immer langsamer als die Ausführung von 1, besonders wenn Sie Datengefahren und lange Pipelines berücksichtigen. Sie versuchen, ein Register in der nächsten Anweisung zu lesen, nachdem Sie es geändert haben, also wenn Ihre CPU das Ergebnis der Stufe N der Pipeline (in der xor ausgeführt wird) auf der Stufe N-1 (wo die inc ist) umgehen kann versuchen, laden das Register, geschweige denn 1 zu seinem Wert hinzufügen), werden Sie Stände haben.

Andere Dinge zu beachten: Anweisung holen Bandbreite (Muss für 16-Bit-Code, beide sind 3 Bytes); mov vermeidet das Ändern von Flags (wahrscheinlich nützlicher, als sie alle auf Null zu setzen); abhängig davon, welche Werte andere Register haben könnten, könnten Sie vielleicht lea ax,[bx+1] (auch 3 Bytes, auch in 32-Bit-Code, keine Auswirkungen auf Flags); wie andere gesagt haben, sbb ax,ax könnte auch unter Umständen funktionieren - es ist auch bei 2 Bytes kürzer.

Wenn Sie mit diesen Arten von Mikro-Optimierungen konfrontiert werden, sollten Sie die Alternativen anstelle von blindly sogar auf Prozessorhandbüchern vergleichen.

P.S. Neue Hausaufgaben: ist xor bx,bx schneller als xor bx,cx (auf jedem Prozessor)?

+2

Zu deiner PS-Frage: Ja, ist es. Bei modernen Prozessoren wird eine xor-Anweisung in zwei identischen Registern von der CPU speziell behandelt, so dass sie keine falsche Abhängigkeit vom vorherigen Wert des Registers hat, die schneller ist und die Anzahl der internen Register reduziert, die die CPU verwenden muss. Einige Prozessoren haben diese Überprüfung für die Unteranweisung nicht, daher ist xor hier vorzuziehen. – fuz

3

Du bist besser dran mit

mov AX, 1

auf der 8086.Wenn Sie Registerinhalte sind Tracking, können Sie möglicherweise besser, wenn Sie wissen, dass zum Beispiel BX bereits 1 hat:

mov AX, BX

oder wenn Sie wissen, dass AH 0:

mov AL, 1

usw.