byte ptr vs. %X%L
-
Erstmal vielen dank für die ausführlichen Antworten!
P.S.: Der 8-Bit-Zugriff (AH) geschieht mit einem eigenen Befehlssatz und hat mit der 32-zu-16-Bit-Umstellung nichts zu tun (anders bei einem 64-Bit-Programm).
Okay, und wie sieht das mit 64-bit aus?
Und nur dann schaltet der Predecoder in einen langsamen Modus:
"When the predecoder encounters an LCP in the fetch line, it must use a slower length decoding algorithm. With the slower length decoding algorithm, the predecoder decodes the fetch in 6 cycles, instead of the usual 1 cycle." (Intel
64 and IA-32 Architectures Optimization Reference Manual, Chapter 3.4.2.3).
Das würde ich gerne auch noch mal genauer wissen, ich werde aus dem Text leider nicht schlau
-
Befehle wie mov reg,mem bleiben gleich, um Kodieraufwand zu sparen. Für mov ah, mem, braucht es keinen Präfix, der ist eindeutig, unabhängig von der Datenpotenz des Prozessors, in dem Sinne, dass immer 8Bit gelten, was man von Begriffen wie "Char" oder "Byte" wohl eher nicht so ableiten kann. Auch bestimmte Standardverhalten des Prozessors kann man mit Präfixen abändern, etwa wenn DS als Standardregister für Daten ist und man ein anderes Register als Standard haben möchte.
Bei 64bit ist es etwas anders, es gibt auch hier Präfixe, aber hier wird u.a. der Virtual Mode nicht unterstützt oder die Adressierweise ist eine andere, bietet mehr Möglichkeiten. Das schaut man sich am besten mal selbst genauer an, etwa hier:
http://www.complang.tuwien.ac.at/ubvl/amd64/amd64h.htmlBei Zeitanalysen muß man auch auf Standardworkflows, Registerabhängigkeiten oder Alignment, Registerrenaming oder diverse Pipline-und Dekodierregeln usw. achten, da macht die Betrachtung oder Vorausbewertung eines einzelnen Befehls ohne Zusammenhang im Zusammenspiel kaum Sinn.
Wenn man 8 Bit aus dem Speicher auslesen will, kann man das auch mit einem 64-Bit-Register. Man liest 64 Bit ein, oder eben 8 Bit + Nullen (= Bit) und liest dementsprechend die Daten. Beim Schreiben gilt das gleiche. Wenn ein ein 8-Bit-Prozessor beschrieben werden soll, dann je nach Einleseprozedur des 8-Bit-Prozessors mit 8 Bits und Nullen.
Wenn man nur 8 Bit ASCIIs ausgeben möchte, dann kann man 64 Bit aus dem Speicher lesen und den Rest mit Bit-Operationen zurechfrisieren, also sowas wie
or rax,00000000000000FF. Aber Bestimmte Befehle zum Stringverarbeiten, wie lodsb oder movsb funktionieren auch bei 64 Bit, nur eben etwas anders als beim 8086. Und die 64 Bit Register haben sogar eine erweiterte Funktionalität in dieser Richtung, so können z.B. auch ESI oder EDI ihre Lowbytes rausgeben.
-
rkhb schrieb:
An meiner Kernaussage "gehupft wie gesprungen" ändert sich aber nichts. Ein Operand Size Override (0x66) ist nur dann ein sogenanntes LCP (Length Changing Prefixes), wenn es tatsächlich die Länge des Befehls ändert:
Ich denke die Änderungen könnten auch jedes Mal durchgeführt werden.
Müssten sich sonst nicht Address-size(0x67) und Register size(0x66h) von Operand size(0x66h) unterscheiden?Ich denke es geht eher darum das Befehle mit solchen Prefixen nicht pararalesisiert werden können und das bei allen Varianten.
Dirk
-
freecrac schrieb:
Ich denke die Änderungen könnten auch jedes Mal durchgeführt werden.
Müssten sich sonst nicht Address-size(0x67) und Register size(0x66h) von Operand size(0x66h) unterscheiden?Das kapier ich jetzt nicht. Welche Änderungen wann von wem? Was soll sich wie warum unterscheiden müssen? 0x66 und 0x67 sind Prefixe, die vor bestimmte Instruktionen geklebt werden - was soll "Address-size(0x67)", "Register size(0x66)" und "Operand Size(0x66)" in diesem Zusammenhang sein?
Ich denke es geht eher darum das Befehle mit solchen Prefixen nicht pararalesisiert werden können und das bei allen Varianten.
Du meinst wahrscheinlich "parallelisiert" und nicht "paralysiert" oder "proletarisiert"
. Eine solche Aussage finde ich aber weder in den Intel- noch in den AMD-Manuals. Auch eine Google-Suche hat mich nicht weitergebracht. Welche Art von Parallelisierung meinst Du und wie wirkt sich das auf die Performance aus?
viele grüße
ralph
-
rkhb schrieb:
freecrac schrieb:
Ich denke die Änderungen könnten auch jedes Mal durchgeführt werden.
Müssten sich sonst nicht Address-size(0x67) und Register size(0x66h) von Operandsize(0x66h) unterscheiden?
Das kapier ich jetzt nicht. Welche Änderungen wann von wem? Was soll sich wie warum
unterscheiden müssen? 0x66 und 0x67 sind Prefixe, die vor bestimmte Instruktionen geklebt
werden - was soll "Address-size(0x67)", "Register size(0x66)" und "Operand Size(0x66)" in
diesem Zusammenhang sein?
Das ein Operand Size Override Prefix die Länge des Operanden immer ändert, so wie auch die Grösse der Adressen und Register sich verändert.
Also auch wenn der Operand mit Immidiate-Wert nur beispielsweise eine 1234h enthählt und die Operandengrösse im 16 Bit-Mode mit Prefix auf 00001234h verändert wird.Nur der x86 backend vom gcc scheint damit ein Problem zu haben.
http://gcc.gnu.org/ml/gcc/2008-06/msg00639.htmlIch denke es geht eher darum das Befehle mit solchen Prefixen nicht pararalesisiert werden können und das bei allen Varianten.
Du meinst wahrscheinlich "parallelisiert" und nicht "paralysiert" oder "proletarisiert"
.
LOL
Eine solche Aussage finde ich aber weder in den Intel- noch in den AMD-Manuals. Auch
eine Google-Suche hat mich nicht weitergebracht. Welche Art von Parallelisierung meinst Du
und wie wirkt sich das auf die Performance aus?
viele grüße
ralphManche Befehle können auf verschieden Pipelines verteilt in einem Taktzyklus paralell ausgeführt werden und einige andere Befehle nicht. Hierbei kann man zwischen komplexeren Befehlen und weniger komplexen Befehlen unterscheiden. Wobei sich weniger komplexe Befehle gut dafür eignen patellel ausgeführt zu werden und komplexere Befehle nur bedigt, oder gar nicht patellel ausgeführt werden können und die anderen Pipelines dann warten müssen, bis ein komplexer Befehl aufgeführt wurde, bis andere Befehle wieder erneut patellel ausgeführt werden können.
http://de.wikipedia.org/wiki/Pipeline_(Prozessor)
http://webster.cs.ucr.edu/AoA/Windows/HTML/CPUArchitecturea3.htmlPerformance:
When the predecoder encounters an LCP in the fetch line, it must use a slower length decoding algorithm. With the slower length decoding algorithm, the predecoder decodes the fetch in 6 cycles, instead of the usual 1 cycle."
Length Changing Prefix Stall:
http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/pentiumm_hh/eventsb/length_changing_prefix_stall.htmDirk
-
freecrac schrieb:
Das ein Operand Size Override Prefix die Länge des Operanden immer ändert, so wie auch die Grösse der Adressen und Register sich verändert.
Nein. Es geht um die Länge der Instruktionen und nicht um die Länge der Operanden, Register oder Adressen.
Ein 'mov eax,ebx' wird im 32-Bit-Mode zu '8B C3' assembliert, ein 'mov ax,bx' zu '66 8B C3'. In diesem Fall hat sich die Länge der eigentlichen Instruktion (8B C3) nicht verändert. Die Länge der Instruktion verändert sich beim Operand Size Prefix nur, wenn eine Instruktion mit einem imm16-Wert folgt. Im diesem Fall ist das Operand Size Prefix ein LCP, im ersten Fall nicht.
Guckt man auf der von Dir verlinkten Homepage sich etwas um, so findet man folgende Seite:
Dort wird gleich als erstes Beispiel für die Befehlsfolge 'mov word ptr a,0x5000 - ret' empfohlen, die Befehlsfolge 'mov eax,0x5000 - mov word ptr a,ax - ret' zu verwenden ("Assembly Alternative 2: No LCP, 3 Instructions"). In der empfohlenen Version kommt allerdings auch ein Operand Size Prefix vor. Und der Autor merkt nicht, dass er ein paar Sätze vorher jedes Operand Size Prefix zu einem LCP erklärt hat...
Manche Befehle können auf verschieden Pipelines verteilt in einem Taktzyklus paralell ausgeführt werden und einige andere Befehle nicht. Hierbei kann man zwischen komplexeren Befehlen und weniger komplexen Befehlen unterscheiden. Wobei sich weniger komplexe Befehle gut dafür eignen patellel ausgeführt zu werden und komplexere Befehle nur bedigt, oder gar nicht patellel ausgeführt werden können und die anderen Pipelines dann warten müssen, bis ein komplexer Befehl aufgeführt wurde, bis andere Befehle wieder erneut patellel ausgeführt werden können.
Und nun mal Butter bei die Fische: Inwieweit ist ein 'mov eax,ebx' komplexer als ein 'mov ax,bx', und zwar so, "dass das Befehle mit solchen Prefixen nicht parallelisiert werden können"? Sehr instruktiv sind in diesem Zusammenhang die Agner-Dokumente:
http://www.agner.org/optimize/
viele grüße
ralph
-
rkhb schrieb:
freecrac schrieb:
Das ein Operand Size Override Prefix die Länge des Operanden immer ändert, so wie auch die Grösse der Adressen und Register sich verändert.
Nein. Es geht um die Länge der Instruktionen und nicht um die Länge der Operanden, Register oder Adressen.
Ein 'mov eax,ebx' wird im 32-Bit-Mode zu '8B C3' assembliert, ein 'mov ax,bx' zu '66 8B C3'. In diesem Fall hat sich die Länge der eigentlichen Instruktion (8B C3) nicht verändert. Die Länge der Instruktion verändert sich beim Operand Size Prefix nur, wenn eine Instruktion mit einem imm16-Wert folgt. Im diesem Fall ist das Operand Size Prefix ein LCP, im ersten Fall nicht.
Mit Prefix wird der Befehl länger, also ohne Prefix. Alle Befehle mit einem Operand Size Prefix verlängern den Befehl immer und jedes Prefix ist ein LCP, da es den Befehl immer länger macht.
Beim 'mov eax,ebx' wird im 32-Bit-Mode kein Operand Size Prefix verwendet, daher gibt es dort auch kein LCP.Guckt man auf der von Dir verlinkten Homepage sich etwas um, so findet man folgende Seite:
Dort wird gleich als erstes Beispiel für die Befehlsfolge 'mov word ptr a,0x5000 - ret' empfohlen, die Befehlsfolge 'mov eax,0x5000 - mov word ptr a,ax - ret' zu verwenden ("Assembly Alternative 2: No LCP, 3 Instructions"). In der empfohlenen Version kommt allerdings auch ein Operand Size Prefix vor. Und der Autor merkt nicht, dass er ein paar Sätze vorher jedes Operand Size Prefix zu einem LCP erklärt hat...
Ja was ist denn daran falsch?
Manche Befehle können auf verschieden Pipelines verteilt in einem Taktzyklus paralell ausgeführt werden und einige andere Befehle nicht. Hierbei kann man zwischen komplexeren Befehlen und weniger komplexen Befehlen unterscheiden. Wobei sich weniger komplexe Befehle gut dafür eignen patellel ausgeführt zu werden und komplexere Befehle nur bedigt, oder gar nicht patellel ausgeführt werden können und die anderen Pipelines dann warten müssen, bis ein komplexer Befehl aufgeführt wurde, bis andere Befehle wieder erneut patellel ausgeführt werden können.
Und nun mal Butter bei die Fische: Inwieweit ist ein 'mov eax,ebx' komplexer als ein 'mov ax,bx', und zwar so, "dass das Befehle mit solchen Prefixen nicht parallelisiert werden können"? Sehr instruktiv sind in diesem Zusammenhang die Agner-Dokumente:
http://www.agner.org/optimize/
viele grüße
ralphJeder Befehl mit Prefix ist ein komplexer Befehl und kann deswegen nur bedingt parallel ausgeführt werden, nur zusammen mit weniger komplexen Befehlen. Zwei solcher komplexeren Befehle im Verbund können auf keinen Fall parallel ausgeführt werden.
Dirk
-
LCP: Cycles Instruction Length Decoder stalls due to length changing prefixes: 66, 67 or REX.W (for EM64T) instructions which change the length of the decoded instruction.
Dirk
-
freecrac schrieb:
Mit Prefix wird der Befehl länger, also ohne Prefix. Alle Befehle mit einem Operand Size Prefix verlängern den Befehl immer und jedes Prefix ist ein LCP, da es den Befehl immer länger macht.
Nein. Diese Schlussfolgerung liegt zwar nahe, aber es scheint, als ob Intel ein Prefix nicht zum Befehl zählen will - es ist eben nur ein Prefix. Genauer wird es in den Agner-Dokumentationen ausgeführt:
"An operand size prefix causes problems if the size of the rest of the instruction is changed by the prefix. Decoder D0 will need an extra clock cycle to re-interpret the instruction. D1 and D2 are stalled in the meantime because the instruction length is re-adjusted. This problem happens when an instruction has a 16-bit immediate operand in 32-bit mode or a 32-bit immediate operand in 16-bit mode. See p. 45 for examples"
(Agner Fog, The microarchitecture of Intel and AMD CPUs, S.60)Dort wird gleich als erstes Beispiel für die Befehlsfolge 'mov word ptr a,0x5000 - ret' empfohlen, die Befehlsfolge 'mov eax,0x5000 - mov word ptr a,ax - ret' zu verwenden ("Assembly Alternative 2: No LCP, 3 Instructions"). In der empfohlenen Version kommt allerdings auch ein Operand Size Prefix vor. Und der Autor merkt nicht, dass er ein paar Sätze vorher jedes Operand Size Prefix zu einem LCP erklärt hat...
Ja was ist denn daran falsch?
In der Spaltenüberschrift steht "... No LCP ...". Im Beispiel kommt ein Operand Size Prefix vor. Also hat der Autor geschlampt oder dieses Prefix ist in diesem Fall kein LCP. Wenn aber ein Operand Size Prefix immer ein LCP ist (wie der Autor vorher suggeriert), dann kann es nicht in diesem Fall keines sein (Logik!).
Jeder Befehl mit Prefix ist ein komplexer Befehl und kann deswegen nur bedingt parallel ausgeführt werden, nur zusammen mit weniger komplexen Befehlen. Zwei solcher komplexeren Befehle im Verbund können auf keinen Fall parallel ausgeführt werden.
Drei nicht nachprüfbare Behauptungen ohne Beleg oder Beispiel.
freecrac schrieb:
LCP: Cycles Instruction Length Decoder stalls due to length changing prefixes: 66, 67 or REX.W (for EM64T) instructions which change the length of the decoded instruction.
Das "which" ist eben die Einschränkung. Nicht alle "66 instructions" sind LCP's. Dieser Autor bringt sogar noch eine Bedingung hinein: Die Länge der dekodierten Instruktion, also die Anzahl der µOps muss sich verändern. Das allerdings halte ich für Humbug.
Zu denken gibt mir, dass bei der Intel-Referenz und auch bei Agner die ganze Problematik nur bei einer bestimmten Mikroarchitektur (Nehalem) behandelt wird.
viele grüße
ralph
-
rkhb schrieb:
freecrac schrieb:
Mit Prefix wird der Befehl länger, also ohne Prefix. Alle Befehle mit einem Operand Size Prefix verlängern den Befehl immer und jedes Prefix ist ein LCP, da es den Befehl immer länger macht.
Nein. Diese Schlussfolgerung liegt zwar nahe, aber es scheint, als ob Intel ein Prefix nicht zum Befehl zählen will - es ist eben nur ein Prefix.
Zur gesamten Befehlslänge wird ein Prefix aber offensichtlich dazu gezählt.
Beispiel:
Intel64 and IA-32 Architectures Software Developer's Manuals3A.pdf: 5-50 Vol. 3
Interrupt 13—General Protection Exception (#GP)
....
Exceeding the instruction length limit of 15 bytes (this only can occur when redundant prefixes are placed before an instruction).
....Genauer wird es in den Agner-Dokumentationen ausgeführt:
"An operand size prefix causes problems if the size of the rest of the instruction is changed by the prefix. Decoder D0 will need an extra clock cycle to re-interpret the instruction. D1 and D2 are stalled in the meantime because the instruction length is re-adjusted. This problem happens when an instruction has a 16-bit immediate operand in 32-bit mode or a 32-bit immediate operand in 16-bit mode. See p. 45 for examples"
(Agner Fog, The microarchitecture of Intel and AMD CPUs, S.60)Dort wird gleich als erstes Beispiel für die Befehlsfolge 'mov word ptr a,0x5000 - ret' empfohlen, die Befehlsfolge 'mov eax,0x5000 - mov word ptr a,ax - ret' zu verwenden ("Assembly Alternative 2: No LCP, 3 Instructions"). In der empfohlenen Version kommt allerdings auch ein Operand Size Prefix vor. Und der Autor merkt nicht, dass er ein paar Sätze vorher jedes Operand Size Prefix zu einem LCP erklärt hat...
Ja was ist denn daran falsch?
In der Spaltenüberschrift steht "... No LCP ...". Im Beispiel kommt ein Operand Size Prefix vor. Also hat der Autor geschlampt oder dieses Prefix ist in diesem Fall kein LCP. Wenn aber ein Operand Size Prefix immer ein LCP ist (wie der Autor vorher suggeriert), dann kann es nicht in diesem Fall keines sein (Logik!).
Jeder Befehl mit Prefix ist ein komplexer Befehl und kann deswegen nur bedingt parallel ausgeführt werden, nur zusammen mit weniger komplexen Befehlen. Zwei solcher komplexeren Befehle im Verbund können auf keinen Fall parallel ausgeführt werden.
Drei nicht nachprüfbare Behauptungen ohne Beleg oder Beispiel.
Ich suche weiter.
freecrac schrieb:
LCP: Cycles Instruction Length Decoder stalls due to length changing prefixes: 66, 67 or REX.W (for EM64T) instructions which change the length of the decoded instruction.
Das "which" ist eben die Einschränkung. Nicht alle "66 instructions" sind LCP's. Dieser Autor bringt sogar noch eine Bedingung hinein: Die Länge der dekodierten Instruktion, also die Anzahl der µOps muss sich verändern. Das allerdings halte ich für Humbug.
Zu denken gibt mir, dass bei der Intel-Referenz und auch bei Agner die ganze Problematik nur bei einer bestimmten Mikroarchitektur (Nehalem) behandelt wird.
viele grüße
ralphEs könnte sein das es hierbei Unterschiede vorhanden sind.
Dirk