Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Rotation in einem Register

6 views
Skip to first unread message

Hipo

unread,
May 23, 2006, 8:16:08 AM5/23/06
to
Hi.
Ich hab noch ein Problem, auf dessen Lösung ich einfachnicht komme.
Ich habe 8 Bytes in einem Register, z.B. RAX. Sie sind wie folgt
angeordnet:

|a b c d e f g h|

Mein Ziel ist es, das Register am Schluss so ausehen zu lassen:

|c d a b g h e f|

Ich muss also die hohen und die niedrigen Byte voneinander unabhängig
rotieren.
Meine Lösung wäre:

ROTL EAX, 16
ROTL RAX, 32
ROTL EAX, 16
ROTL RAX, 32

Ich finde das nicht elegant, und sicherlich nicht sher effizient, da ich
diese Berechnung sehr oft durchlaufen muss.

Hat vielleicht jemand einen Trick auf Lager, der diese Operation
effizienter erledigen kann?

mfg, Hipo

Sebastian Biallas

unread,
May 23, 2006, 9:41:13 AM5/23/06
to
Hipo wrote:
> Hi.
> Ich hab noch ein Problem, auf dessen Lösung ich einfachnicht komme.
> Ich habe 8 Bytes in einem Register, z.B. RAX. Sie sind wie folgt
> angeordnet:
>
> |a b c d e f g h|
>
> Mein Ziel ist es, das Register am Schluss so ausehen zu lassen:
>
> |c d a b g h e f|
>
> Ich muss also die hohen und die niedrigen Byte voneinander unabhängig
> rotieren.
> Meine Lösung wäre:
>
> ROTL EAX, 16

Das löscht den oberen Teil von RAX. Hast Du das überhaupt ausprobiert?

> Hat vielleicht jemand einen Trick auf Lager, der diese Operation
> effizienter erledigen kann?

pshufw

Ansonsten würde ich den Wert in EDX:EAX speichern. Was versuchst Du da
eigentlich zu erreichen?

--
Gruß,
Sebastian

Hipo

unread,
May 23, 2006, 9:56:20 AM5/23/06
to
Sebastian Biallas schrieb:

> Hipo wrote:
>> Hi.
>> Ich hab noch ein Problem, auf dessen Lösung ich einfachnicht komme.
>> Ich habe 8 Bytes in einem Register, z.B. RAX. Sie sind wie folgt
>> angeordnet:
>>
>> |a b c d e f g h|
>>
>> Mein Ziel ist es, das Register am Schluss so ausehen zu lassen:
>>
>> |c d a b g h e f|
>>
>> Ich muss also die hohen und die niedrigen Byte voneinander unabhängig
>> rotieren.
>> Meine Lösung wäre:
>>
>> ROTL EAX, 16
>
> Das löscht den oberen Teil von RAX. Hast Du das überhaupt ausprobiert?

Ich bin noch in der Planungsphase. Ich hätte es gern ausprobiert, aber
VS 2005 für x64 unterstützt keinen inline assembler. Bisher hatte ich
noch keine Zeit reinen Assembler code zu schreiben, wobei ich mich da
erst einlesen muss, da ich es noch nicht verwerendet hab.

>> Hat vielleicht jemand einen Trick auf Lager, der diese Operation
>> effizienter erledigen kann?
>
> pshufw

Kannst du mir aus Erfahrung sagen, wie sehr die Performance unter
Datentransfers zwischen XMM und GPR Register leidet. Ich habe
diesbezüglich bereits einige Warnungen erhalten.


>
> Ansonsten würde ich den Wert in EDX:EAX speichern. Was versuchst Du da
> eigentlich zu erreichen?

Für einen Teil eines Verschlüsselungsalgorithmus muss ich oben
beschriebene Permutationen durchführen.

mfg, Hipo

Sebastian Biallas

unread,
May 23, 2006, 10:11:49 AM5/23/06
to
Hipo wrote:
>> pshufw
>
> Kannst du mir aus Erfahrung sagen, wie sehr die Performance unter
> Datentransfers zwischen XMM und GPR Register leidet. Ich habe
> diesbezüglich bereits einige Warnungen erhalten.

Wahrscheinlich zu recht. Besser ist es, alles mit MMX/SSE zu machen.

--
Gruß,
Sebastian

Jan Bruns

unread,
May 23, 2006, 8:21:40 PM5/23/06
to

"Hipo":

> Ich hab noch ein Problem, auf dessen Lösung ich einfachnicht komme.
> Ich habe 8 Bytes in einem Register, z.B. RAX. Sie sind wie folgt
> angeordnet:

> |a b c d e f g h|

> Mein Ziel ist es, das Register am Schluss so ausehen zu lassen:
>
> |c d a b g h e f|


Also mal in 32-Bit Schreibweise (für 64 Bit lässt sich das sicherlich
einfach erweitern):

; "eax=a,b,c,d -> eax=c,d,a,b"
mov ebx,eax
and eax,$FFFF0000
and ebx,$0000FFFF
shr eax,16
shl ebx,16
or eax,ebx

oder einfach:

; "eax=a,b,c,d -> eax=c,d,a,b"
rol eax,16

letzteres is so natürlich nicht auf 64-Bit übertragbar.

Gruss

Jan Bruns

Jan Bruns

unread,
May 23, 2006, 8:27:15 PM5/23/06
to
"Sebastian Biallas":
> Hipo wrote:

>> ROTL EAX, 16

> Das löscht den oberen Teil von RAX. Hast Du das überhaupt ausprobiert?

Wie heisst denn in dieser neumodischen 64-Bit Technik der Befehl
für Rotation? Gab doch schon immer rot und shift, mit und ohne Carry.

Grussauch

Sebastian Biallas

unread,
May 23, 2006, 8:58:20 PM5/23/06
to
Jan Bruns wrote:
> "Sebastian Biallas":
>> Hipo wrote:
>
>>> ROTL EAX, 16
>
>> Das löscht den oberen Teil von RAX. Hast Du das überhaupt ausprobiert?
>
> Wie heisst denn in dieser neumodischen 64-Bit Technik der Befehl
> für Rotation?

Weiterhin rol bzw. ror usw, das da oben ist wahrscheinlich ein
Tippfehler. Es hat sich von 32->64 am Befehlssatz eigentlich kaum was
geändert. Ein paar Befehle sind rausgeflogen, hinzu kam eigentlich nur
movsxd, ein neuer Adressierungsmodus (IP-relativ), ein bissl SSE-Kram
und esoterisches. Und man hat halt doppelt so viele Register.

Man sollte halt nur wissen, dass beim Zugriff auf ein Teilregister immer
die oberen 32 Bit gelöscht werden.

Die Aufgabe des OP ist für ein 64 Bit Register wohl nicht so einfach,
deshalb mein Vorschlag, auf zwei 32 Bit Register auszuweichen.

--
Gruß,
Sebastian

Jan Bruns

unread,
May 23, 2006, 9:22:49 PM5/23/06
to

"Sebastian Biallas":

> Man sollte halt nur wissen, dass beim Zugriff auf ein Teilregister immer
> die oberen 32 Bit gelöscht werden.

Das muss ich bei Gelegenheit mal nachschlagen...

Ist ja bisher auch anders gewesen:

mov eax,$12345678
mov ax, $5678
mov al, $78

-> eax = $12345678

Sebastian Biallas

unread,
May 24, 2006, 5:55:02 AM5/24/06
to

Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.

Das ist aber auch sinnvoll so. Obiges Verhalten war vor 20 Jahren
vielleicht noch verständlich, ist aber für heutige Prozessoren sehr
schlecht, weil man mit den partial register stalls umgehen muss.

Bei dem "mov al, $78" muss der Prozessor entweder auf den Wert von rax
warten, bis er den Befehl zuende ausführen kann, oder er zerteilt das
Register und muss es später u.U. wieder kompliziert zusammenführen. Ein
"mov eax, $78" hingegen kann er unabhängig von dem vorigen Wert von rax
ausführen.

Schau Dir mal Code vom einem aktuellen Compiler an, der mit Bytes
handtiert (z.B. Stringverarbeitung). Der ist voll von scheinbar
unnötigen movzx/movsx. Das macht man halt, um dem Prozessor Arbeit
abzunehmen.

--
Gruß,
Sebastian

Jan Bruns

unread,
May 24, 2006, 12:27:37 PM5/24/06
to

"Sebastian Biallas":

> Jan Bruns wrote:
>> "Sebastian Biallas":

>> mov eax,$12345678


>> mov ax, $5678
>> mov al, $78

>> -> eax = $12345678

> Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.

Naja, interessiert mich momentan nicht hinreichend, um das nachzuschlagen.
Jedenfalls: Ziemlich inkonsequent sieht das aus.

> Das ist aber auch sinnvoll so. Obiges Verhalten war vor 20 Jahren
> vielleicht noch verständlich, ist aber für heutige Prozessoren sehr
> schlecht, weil man mit den partial register stalls umgehen muss.

Also ich kann nun nicht gerade behaupten, über die pipelinetechnsichen
Hintergründe bzgl. partieller Register genauestens informiert zu sein.
Klingt für mich eigentlich eher nach Integrationsdichte, als nach
echten Engpässen.

> Bei dem "mov al, $78" muss der Prozessor entweder auf den Wert von rax
> warten, bis er den Befehl zuende ausführen kann, oder er zerteilt das
> Register und muss es später u.U. wieder kompliziert zusammenführen. Ein
> "mov eax, $78" hingegen kann er unabhängig von dem vorigen Wert von rax
> ausführen.

Der Prozessor muss auf rax warten? Wo ist denn rax implementiert?

Du meinst wahrscheinlich einfach irgendeine zentrale Verarbeitungseinheit
in der CPU. Dazu ist einfach mal festzustellen, daß es neben schematischen
Trennung von Befehlausführung und Registersatz auch völlig andere
Implementationen denkbar sind. Bspw. könnte man für jedes Register
eine eigene Ausführungseinheit vorsehen, um dann nur noch Datentransfers
zwischen Registern bzw. externem Speicher zentralisiert organisieren zu
müssen. In Anbetracht der "aktuellen" Problematik weiterhin schnell
steigende(r) Integrationsumfang/dichte bei geringem Taktratenzuwachs
vielleicht nichtmal eine völlig absurde Vorgehensweise.

> Schau Dir mal Code vom einem aktuellen Compiler an, der mit Bytes
> handtiert (z.B. Stringverarbeitung). Der ist voll von scheinbar
> unnötigen movzx/movsx. Das macht man halt, um dem Prozessor Arbeit
> abzunehmen.

Also Du meinst den Zusammenhang, daß obwohl nur bspw. vereinzelte
Bytes zu verarbeiten sind (von denen mehrere in einem Register
gespeichert werden könnten), in der Praxis trotzdem regelmässig nur
eine Dateneinheit pro Register verwendet wird, und dabei denn auch
unnötig häufig die nicht verwendeten Anteile explizit überschrieben
werden?

Das hat vielleicht verschiedene Ursachen, aber einer davon ist
sicherlich memory alignment. Wenn es dagegen darum geht, bspw.
den Befehl "mov al,bl" CPU-optimiert zu schreiben, kam da
bislang regelmässig sowas wie "mov eax,ebx" heraus, wenn die
oberen Anteile von ebx eh' trivial sind, obwohl die Formulierung
"movzx eax,bl" sicherlich einfacher ist.

Gruss

Jan Bruns


Sebastian Biallas

unread,
May 24, 2006, 1:01:12 PM5/24/06
to
Jan Bruns wrote:
> "Sebastian Biallas":
>> Jan Bruns wrote:
>>> "Sebastian Biallas":
>
>>> mov eax,$12345678
>>> mov ax, $5678
>>> mov al, $78
>
>>> -> eax = $12345678
>
>> Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.
>
> Naja, interessiert mich momentan nicht hinreichend, um das nachzuschlagen.
> Jedenfalls: Ziemlich inkonsequent sieht das aus.

Es war aber nötig, ansonsten hätte man immer mit den 64 Bit Registern
arbeiten müssen, wenn man den Code nicht unnötig verlangsamen möchte.

>
>> Das ist aber auch sinnvoll so. Obiges Verhalten war vor 20 Jahren
>> vielleicht noch verständlich, ist aber für heutige Prozessoren sehr
>> schlecht, weil man mit den partial register stalls umgehen muss.
>
> Also ich kann nun nicht gerade behaupten, über die pipelinetechnsichen
> Hintergründe bzgl. partieller Register genauestens informiert zu sein.
> Klingt für mich eigentlich eher nach Integrationsdichte, als nach
> echten Engpässen.

Ich weiß nicht, was Du mit Integrationsdichte meinst.

>
>> Bei dem "mov al, $78" muss der Prozessor entweder auf den Wert von rax
>> warten, bis er den Befehl zuende ausführen kann, oder er zerteilt das
>> Register und muss es später u.U. wieder kompliziert zusammenführen. Ein
>> "mov eax, $78" hingegen kann er unabhängig von dem vorigen Wert von rax
>> ausführen.
>
> Der Prozessor muss auf rax warten? Wo ist denn rax implementiert?

Der Prozessor hat vielleicht 64 Register von denen mehrere den Wert von
rax zu einem bestimmten Zeitpunkt enthalten können. Nehmen wir z.B. so
einen Code:

mov eax, 1
push eax
mov eax, 2
push eax

Der Prozessor kann hier die beiden movs parallel ausführen (in
verschiende interne Register), da sie von nichts abhängen.

Würde jedoch "mov eax, 1" den oberen Teil von rax erhalten, dann gibt es
zwei Möglichkeiten:

1) Der "mov eax, 2" wird erst ausgeführt, wenn der finale Wert von rax
bekannt ist (dh. bis alle Anweisungen davor, die rax anfassen,
bearbeitet sind).
2) Der Prozessor teilt rax auf verschiedene interne Register auf. Falls
danach rax gelesen wird, muss der Prozessor die internen Register wieder
zusammenfassen.

Beides ist nicht schön.

> Du meinst wahrscheinlich einfach irgendeine zentrale Verarbeitungseinheit
> in der CPU. Dazu ist einfach mal festzustellen, daß es neben schematischen
> Trennung von Befehlausführung und Registersatz auch völlig andere
> Implementationen denkbar sind. Bspw. könnte man für jedes Register
> eine eigene Ausführungseinheit vorsehen, um dann nur noch Datentransfers
> zwischen Registern bzw. externem Speicher zentralisiert organisieren zu
> müssen. In Anbetracht der "aktuellen" Problematik weiterhin schnell
> steigende(r) Integrationsumfang/dichte bei geringem Taktratenzuwachs
> vielleicht nichtmal eine völlig absurde Vorgehensweise.

Ich bin kein Prozessorhersteller, und ich kann nur die momentane
Situation reflektieren.

>
>> Schau Dir mal Code vom einem aktuellen Compiler an, der mit Bytes
>> handtiert (z.B. Stringverarbeitung). Der ist voll von scheinbar
>> unnötigen movzx/movsx. Das macht man halt, um dem Prozessor Arbeit
>> abzunehmen.
>
> Also Du meinst den Zusammenhang, daß obwohl nur bspw. vereinzelte
> Bytes zu verarbeiten sind (von denen mehrere in einem Register
> gespeichert werden könnten), in der Praxis trotzdem regelmässig nur
> eine Dateneinheit pro Register verwendet wird, und dabei denn auch
> unnötig häufig die nicht verwendeten Anteile explizit überschrieben
> werden?

Nein. Dass ah usw. nicht mehr verwendet werden, hat zwar ähnliche
Ursachen, aber das meine ich nicht.

Ich meine z.B. sowas:

movzx eax, [byte1]
movzx ecx, [byte2]
cmp eax, ecx

statt:

mov al, [byte1]
mov cl, [byte2]
cmp al, cl

Ein "movzx eax, .." kann unabhängig davon ausgeführt werden, was in eax
steht. Bei "mov al, .." haben wir die Situation, die ich oben
beschrieben habe.

>
> Das hat vielleicht verschiedene Ursachen, aber einer davon ist
> sicherlich memory alignment.

Nein, das hat mit Alignment nichts zu tun. Byte-Zugriffe sind immer aligned.

--
Gruß,
Sebastian

Jan Bruns

unread,
May 24, 2006, 3:36:16 PM5/24/06
to

"Sebastian Biallas":
> Jan Bruns wrote:
>> "Sebastian Biallas":
>>> Jan Bruns wrote:
>>>> "Sebastian Biallas":

>>>> mov eax,$12345678
>>>> mov ax, $5678
>>>> mov al, $78
>>>> -> eax = $12345678
>>> Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.

>> Naja, interessiert mich momentan nicht hinreichend, um das nachzuschlagen.
>> Jedenfalls: Ziemlich inkonsequent sieht das aus.

> Es war aber nötig, ansonsten hätte man immer mit den 64 Bit Registern
> arbeiten müssen, wenn man den Code nicht unnötig verlangsamen möchte.

Nee, komm, also Notwendigkeit ist wat anners.

Arbeitet man nicht ohnehin immer mit 64-Bit Registern?

>>> Das ist aber auch sinnvoll so. Obiges Verhalten war vor 20 Jahren
>>> vielleicht noch verständlich, ist aber für heutige Prozessoren sehr
>>> schlecht, weil man mit den partial register stalls umgehen muss.

>> Also ich kann nun nicht gerade behaupten, über die pipelinetechnsichen
>> Hintergründe bzgl. partieller Register genauestens informiert zu sein.
>> Klingt für mich eigentlich eher nach Integrationsdichte, als nach
>> echten Engpässen.

> Ich weiß nicht, was Du mit Integrationsdichte meinst.

Damit habe ich die Transitoranzahl gemeint. Ist üblich.

>>> Bei dem "mov al, $78" muss der Prozessor entweder auf den Wert von rax
>>> warten, bis er den Befehl zuende ausführen kann, oder er zerteilt das
>>> Register und muss es später u.U. wieder kompliziert zusammenführen. Ein
>>> "mov eax, $78" hingegen kann er unabhängig von dem vorigen Wert von rax
>>> ausführen.

>> Der Prozessor muss auf rax warten? Wo ist denn rax implementiert?

> Der Prozessor hat vielleicht 64 Register von denen mehrere den Wert von
> rax zu einem bestimmten Zeitpunkt enthalten können. Nehmen wir z.B. so
> einen Code:

> [...]


> Der Prozessor kann hier die beiden movs parallel ausführen (in
> verschiende interne Register), da sie von nichts abhängen.

> Würde jedoch "mov eax, 1" den oberen Teil von rax erhalten, dann gibt es
> zwei Möglichkeiten:

Hier hast Du nun erstmal die Möglichkeit vergessen, daß man dann doch
durchaus auch movzx schreiben könnte, um exakt die obige Situation
zu konstruieren.

> 1) Der "mov eax, 2" wird erst ausgeführt, wenn der finale Wert von rax
> bekannt ist (dh. bis alle Anweisungen davor, die rax anfassen,
> bearbeitet sind).
> 2) Der Prozessor teilt rax auf verschiedene interne Register auf. Falls
> danach rax gelesen wird, muss der Prozessor die internen Register wieder
> zusammenfassen.

> Beides ist nicht schön.

Naja, das hattest Du ja schon geschrieben. Ist ja auch nett, wenn Du
versuchst, die aktuellen Gegebenheiten zu beschreiben.

>> Du meinst wahrscheinlich einfach irgendeine zentrale Verarbeitungseinheit
>> in der CPU. Dazu ist einfach mal festzustellen, daß es neben schematischen
>> Trennung von Befehlausführung und Registersatz auch völlig andere
>> Implementationen denkbar sind. Bspw. könnte man für jedes Register
>> eine eigene Ausführungseinheit vorsehen, um dann nur noch Datentransfers
>> zwischen Registern bzw. externem Speicher zentralisiert organisieren zu
>> müssen. In Anbetracht der "aktuellen" Problematik weiterhin schnell
>> steigende(r) Integrationsumfang/dichte bei geringem Taktratenzuwachs
>> vielleicht nichtmal eine völlig absurde Vorgehensweise.

> Ich bin kein Prozessorhersteller, und ich kann nur die momentane
> Situation reflektieren.

So wie du hier argumentierst wäre es aber doch ganz sinnig, wenn Du
wenigstens bezüglich dieses Details (zentrales execute auf "externem"
Registerspeicher) irgendwelche Zukunftserwartungen hättest.

Worauf willst Du sonst die Begriffe "notwendig, logisch, sinnvoll"
stützen?

>> Das hat vielleicht verschiedene Ursachen, aber einer davon ist
>> sicherlich memory alignment.

> Nein, das hat mit Alignment nichts zu tun. Byte-Zugriffe sind
> immer aligned.

Sehe ich anders, is aber echt egal.

gruss

Jan Bruns

Sebastian Biallas

unread,
May 25, 2006, 5:25:04 PM5/25/06
to
Jan Bruns wrote:
> "Sebastian Biallas":
>> Jan Bruns wrote:
>>> "Sebastian Biallas":
>> Es war aber nötig, ansonsten hätte man immer mit den 64 Bit Registern
>> arbeiten müssen, wenn man den Code nicht unnötig verlangsamen möchte.
>
> Nee, komm, also Notwendigkeit ist wat anners.
>
> Arbeitet man nicht ohnehin immer mit 64-Bit Registern?

Da ein int üblicherweise noch 32 Bit groß ist, arbeitet man häufig noch
mit 32 Bit Registern.

>>> Also ich kann nun nicht gerade behaupten, über die pipelinetechnsichen
>>> Hintergründe bzgl. partieller Register genauestens informiert zu sein.
>>> Klingt für mich eigentlich eher nach Integrationsdichte, als nach
>>> echten Engpässen.
>
>> Ich weiß nicht, was Du mit Integrationsdichte meinst.
>
> Damit habe ich die Transitoranzahl gemeint. Ist üblich.

Ich verstehe trotzdem nicht, wie Du das Problem lösen willst, indem Du
da Transistoren hinterherwirfst.

>> Würde jedoch "mov eax, 1" den oberen Teil von rax erhalten, dann gibt es
>> zwei Möglichkeiten:
>
> Hier hast Du nun erstmal die Möglichkeit vergessen, daß man dann doch
> durchaus auch movzx schreiben könnte, um exakt die obige Situation
> zu konstruieren.

Also müsste man den Code mit movzx vollmachen.

>> Ich bin kein Prozessorhersteller, und ich kann nur die momentane
>> Situation reflektieren.
>
> So wie du hier argumentierst wäre es aber doch ganz sinnig, wenn Du
> wenigstens bezüglich dieses Details (zentrales execute auf "externem"
> Registerspeicher) irgendwelche Zukunftserwartungen hättest.

Dann beschreib doch mal, wie es besser gehen sollte.

>>> Das hat vielleicht verschiedene Ursachen, aber einer davon ist
>>> sicherlich memory alignment.
>
>> Nein, das hat mit Alignment nichts zu tun. Byte-Zugriffe sind
>> immer aligned.
>
> Sehe ich anders, is aber echt egal.

Wie definierst Du denn Aligment? Und warum soll movzx daran etwas ändern?

--
Gruß,
Sebastian

Jan Bruns

unread,
May 25, 2006, 7:09:07 PM5/25/06
to

"Sebastian Biallas":
> Jan Bruns wrote:
>> "Sebastian Biallas":
>>> Jan Bruns wrote:
>>>> "Sebastian Biallas":

>>>> Also ich kann nun nicht gerade behaupten, über die pipelinetechnsichen
>>>> Hintergründe bzgl. partieller Register genauestens informiert zu sein.
>>>> Klingt für mich eigentlich eher nach Integrationsdichte, als nach
>>>> echten Engpässen.

>>> Ich weiß nicht, was Du mit Integrationsdichte meinst.

>> Damit habe ich die Transitoranzahl gemeint. Ist üblich.

> Ich verstehe trotzdem nicht, wie Du das Problem lösen willst, indem Du
> da Transistoren hinterherwirfst.

Vielleicht so, wie es gemacht wird, wenn ich bspw. in 32-Bit Code
"and eax,ebx" schreibe. Wenn im gleichen Code irgendwo "and ax,bx"
steht, und genau das die Pipeline verwirrt, dann hat da doch wohl
höchstwahrscheinlich irgendwer keine Lust gehabt, sich um solche
Details zu kümmern.

Klar, in den Broschüren der Hersteller heisst "keine Lust gehabt"
dann auch gerne mal "technisch notwendig" (sorry, ich hatte in letzter
Zeit etwas viel mit GPUs zu tun, da sehen die Hersteller sowas noch
recht "locker").


>> So wie du hier argumentierst wäre es aber doch ganz sinnig, wenn Du
>> wenigstens bezüglich dieses Details (zentrales execute auf "externem"
>> Registerspeicher) irgendwelche Zukunftserwartungen hättest.

> Dann beschreib doch mal, wie es besser gehen sollte.

Von sollen hab' ich nix geschrieben.
Ich schrieb was von: könnte sein, daß das auch anders gut geht.
Weiß ich doch nicht. Bin kein CPU-Hersteller. Du auch nicht,
schreibst Du. Von daher kämen wir besser mit'nander aus,
wenn Du statt

| Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.
|

| Das ist aber auch sinnvoll so. Obiges Verhalten war vor 20 Jahren
| vielleicht noch verständlich, ist aber für heutige Prozessoren sehr
| schlecht, weil man mit den partial register stalls umgehen muss.

besser sowas schriebest:

< Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.
<

< Das soll für moderne CPUs aktuell technisch sinnvoll sein, weil dann...
< [Ausführung zum Thema zentralisierte Execute-Einheit und ihre Register].

Gruss

Jan Bruns


Sebastian Biallas

unread,
May 25, 2006, 7:33:32 PM5/25/06
to
Jan Bruns wrote:
>
> Vielleicht so, wie es gemacht wird, wenn ich bspw. in 32-Bit Code
> "and eax,ebx" schreibe. Wenn im gleichen Code irgendwo "and ax,bx"
> steht, und genau das die Pipeline verwirrt, dann hat da doch wohl
> höchstwahrscheinlich irgendwer keine Lust gehabt, sich um solche
> Details zu kümmern.

Das ist natürlich möglich. Allerdings stehen Intel und AMD in
Konkurrenzkampf und keiner der beiden hat es geschafft das Problem in
soweit zu lösen, dass es "kein Problem" mehr ist.

> Klar, in den Broschüren der Hersteller heisst "keine Lust gehabt"
> dann auch gerne mal "technisch notwendig" (sorry, ich hatte in letzter
> Zeit etwas viel mit GPUs zu tun, da sehen die Hersteller sowas noch
> recht "locker").

Die ISA wurde halt so angelegt, dass der "Normalfall" möglich effizient
von der CPU behandelt werden kann. Dies halte ich grundsätzlich für
nachvollziehbar und sinnvoll.

>>> So wie du hier argumentierst wäre es aber doch ganz sinnig, wenn Du
>>> wenigstens bezüglich dieses Details (zentrales execute auf "externem"
>>> Registerspeicher) irgendwelche Zukunftserwartungen hättest.
>
>> Dann beschreib doch mal, wie es besser gehen sollte.
>
> Von sollen hab' ich nix geschrieben.
> Ich schrieb was von: könnte sein, daß das auch anders gut geht.

Natürlich kann das sein. Da aber offenbar keiner eine Lösung dafür
kennt, hat man das Problem des partiellen Registerzugriffs bei x86_64
direkt vermieden (wie es z.B. PowerPC schon vor Jahrzehnten vorgemacht hat).

> Weiß ich doch nicht. Bin kein CPU-Hersteller. Du auch nicht,
> schreibst Du. Von daher kämen wir besser mit'nander aus,
> wenn Du statt
>
> | Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.
> |
> | Das ist aber auch sinnvoll so. Obiges Verhalten war vor 20 Jahren
> | vielleicht noch verständlich, ist aber für heutige Prozessoren sehr
> | schlecht, weil man mit den partial register stalls umgehen muss.
>
> besser sowas schriebest:
>
> < Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.
> <
> < Das soll für moderne CPUs aktuell technisch sinnvoll sein, weil dann...
> < [Ausführung zum Thema zentralisierte Execute-Einheit und ihre Register].

Warum? Wenn man partiellen Registerzugriff erlaubt, dann muss die CPU
sich auch damit rumschlagen (das sollte offensichtlich sein). Und dass
es für heutige Prozessoren schlecht ist, kann man aus den Intel und AMD
Dokumentationen entnehmen.

--
Gruß,
Sebastian

Florian Liebig

unread,
Jun 7, 2006, 9:23:25 AM6/7/06
to
hi, hipo!

sieht ganz nach einem big-endian zu little-endian mit shifting
algorithmus
aus.
kennst du den damals dafuer entstandenen befehl bswap ??
vielleicht kannst du damit eleganteren code schreiben.
nur kenn ich leider die neuen 64bit register regeln nicht so genau.
aber vielleicht geht ja dies:
BSWAP rax
ROL/ROR rax,32

gruss florian.

Sebastian Biallas

unread,
Jun 7, 2006, 9:42:50 AM6/7/06
to
Florian Liebig wrote:

rax = |a b c d e f g h|
> BSWAP rax
rax = |h g f e d c b a|
> ROL/ROR rax,32
rax = |d c b a h g f e|

Der OP wollte aber rax = |c d a b g h e f| erreichen...

--
Gruß,
Sebastian

Florian Liebig

unread,
Jun 12, 2006, 2:24:53 PM6/12/06
to
hi sebastian!

na klar, wie du sagst.
ich habe mich in seinem post etwas verlesen.

Herbert Glarner

unread,
Jul 15, 2006, 12:05:38 PM7/15/06
to
Hipo wrote:
> |a b c d e f g h|
> Mein Ziel ist es, das Register am Schluss so ausehen zu lassen:
> |c d a b g h e f|

Wie auch immer die 64bit-Dinger heissen mögen:

A = B [abcdefgh]
A linksrotate 16 bit [cdefghab]
B rechtsrotate 16 bit [ghabcdef]
A and ffff0000ffff0000 [cd--gh--]
B and 0000ffff0000ffff [--ab--ef]
A or B [cdabghef]

Schneller kanns nicht wirklich gehen.

Freundliche Grüsse
//Herbert Glarner

--
http://herbert.wikispaces.com

0 new messages