PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Integer Arithmetik mit der Adress-Unit


liquid
2004-05-05, 14:38:27
Hiho,

ich habe vor einiger Zeit mal etwas darüber gelesen, dass es möglich wäre mit der Adressierungseinheit der CPU einfache Integerarithmetik durchzuführen (ich glaubes ging mit lea).

Weiß jemand ob das korrekt ist und wie man da genau vorgeht? Eventuell auch Link?

Danke schonmal im voraus!

cya
liquid

HajottV
2004-05-05, 17:02:53
Original geschrieben von liquid
ich habe vor einiger Zeit mal etwas darüber gelesen, dass es möglich wäre mit der Adressierungseinheit der CPU einfache Integerarithmetik durchzuführen (ich glaubes ging mit lea).


Jup. LEA berechnet die effektive Adresse und schiebt sie in ein Register, man kann damit also alle Operationen nutzen, die bei der Adressberechnung möglich sind.

LEA EAX, [EBX * 4 + EDX + 100]

entspricht:

EAX = EBX * 4 + EDX + 100

Reicht das als Antwort?

Gruß

Jörg

liquid
2004-05-05, 17:12:35
Jep, thx @ HajottV!
Jetzt muss ich das nur noch in AT&T Assembler ummodeln.

cya
liquid

GloomY
2004-05-05, 22:20:12
Original geschrieben von liquid
Jep, thx @ HajottV!
Jetzt muss ich das nur noch in AT&T Assembler ummodeln.

cya
liquid Vielleicht hilft das: http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html

edit: Heißt das, dass man die AGUs des Prozessors für (einfache) Integer-Arithmetik missbrauchen kann? Oder läuft der LEA-Befehl auch über die ALUs?

liquid
2004-05-05, 23:36:32
Thx@GloomY aber kenne ich bereits.

cya
liquid

Xmas
2004-05-06, 11:40:26
Original geschrieben von GloomY
edit: Heißt das, dass man die AGUs des Prozessors für (einfache) Integer-Arithmetik missbrauchen kann? Oder läuft der LEA-Befehl auch über die ALUs?
Genau das heißt es... je nach CPU allerdings. Wenn ich es recht in Erinnerung hab nimmt der P4 die ALU, oder zumindest ist LEA langsamer.

HajottV
2004-05-06, 12:54:04
Original geschrieben von Xmas
Genau das heißt es... je nach CPU allerdings. Wenn ich es recht in Erinnerung hab nimmt der P4 die ALU, oder zumindest ist LEA langsamer.

(Ich würde bei keinem modernerem Prozessor mehr von ALU sprechen, dafür sind da einfach viel zu viele parallele Einheiten.)

Benutzt man LEA in der Form

LEA reg, [reg * scale + reg + disp],

dann wird in der Tat ein zusätzlicher Takt benötigt (das gilt allerdings auch für den P3). Beim P4 wird das scale (wenn scale > 1) in der shift-Einheit ausgeführt, d.h. diese ist dann für einen Takt blockiert.

LEA EAX, [ECX + EDX + 4]

ist schneller als

MOV EAX, ECX
ADD EAX, EDX
ADD EAX, 4

Aber:

LEA EAX, [ECX * 2 + EDX + 4]

ist langsamer als

MOV EAX, ECX
ADD EAX, ECX
ADD EAX, EDX
ADD EAX, 4

Wobei die P4 Pipeline dermaßen kompliziert ist, daß das nicht unbedingt immer so sein muß. Das hängt extrem davon ab, wie die Pipeline gefüllt ist und was davor und danach passiert.

Gruß

Jörg

zeckensack
2004-05-07, 12:35:04
Original geschrieben von GloomY
Vielleicht hilft das: http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html

edit: Heißt das, dass man die AGUs des Prozessors für (einfache) Integer-Arithmetik missbrauchen kann? Oder läuft der LEA-Befehl auch über die ALUs? Siehe HajottV. K7 und K8 können's in ihren dedizierten AGUs rechnen (und damit die echten ALUs für andere Instruktionen freimachen - der K7 hat volle 9 issue ports).

GloomY
2004-05-07, 17:28:45
Original geschrieben von zeckensack
Siehe HajottV. K7 und K8 können's in ihren dedizierten AGUs rechnen (und damit die echten ALUs für andere Instruktionen freimachen - der K7 hat volle 9 issue ports). Ah :) Jetzt versteh' ich endlich mal, was das mit den Issue Ports auf sich hat =)

liquid
2004-05-08, 13:00:01
Jetzt tut sich doch wieder ein Problem auf.

Ich habe in ECX ein Index stehen, der in ein Array indiziert.

"movl (%1), %%ecx \n\t" // ECX = index-A
"leal (%2, %%ecx, 12), %%ecx \n\t"
"addl $4, %1 \n\t"

Kurz zur Erklärung. In ECX liegt wie gesagt nach dem ersten movl Aufruf der Index. Dann wollte ich mit lea den Index in einen Pointer umwandeln.

%2 ist Base. ECX ist Index und 12 ist Indexscale. Aber die Sache hat ja nen Haken, 12 ist keine 2er Potenz. Das funzt also nicht. Jetzt muss ich irgendwie den Index vorher scalen (mit Faktor 12). Wie sollte ich das am besten machen?

Ich habe mir gedacht. Das Ding einmal mit 4 multiplizieren (2 mal shiften) und dann zweimal zueinander addieren, aber das funzt ja so auch nicht. Oder ich könnte den Index in EDX kopieren (das einzige GPR was momentan noch frei ist), dort mit 4 multiplizieren (wieder shiften), in ECX mit 8 multiplizieren und dann nachher addieren.

Was meint ihr? Wie gehe ich das am elegantesten an?

cya
liquid

HajottV
2004-05-08, 14:16:33
Original geschrieben von liquid

"movl (%1), %%ecx \n\t" // ECX = index-A
"leal (%2, %%ecx, 12), %%ecx \n\t"
"addl $4, %1 \n\t"

Was ist denn das für eine Notation? O_o


Ich würde es so machen:

LEA ECX,[ECX * 2 + ECX] (ECX mit 3 multiplizieren)

und dann [ECX * 4 + %2] benutzen.

Gruß

Jörg

liquid
2004-05-08, 14:31:35
Das ist AT&T Syntax.

Hmm, die Idee gefällt mir, mal gucken.

cya
liquid