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

cache coherence

2 views
Skip to first unread message

Jan Bruns

unread,
Dec 3, 2014, 11:57:56 PM12/3/14
to


Hallo.

Ich hab da mal eine Frage zum Thema "cache coherence"
zwischen CPU Kernen: Wie verlässlich und in welcher
Absolutheit ist eine solche denn inzwischen
üblicherweise (d.h. hier auch: low budget) gegeben?

Also Anlass zu der Frage ist eigentlich nur, daß halt
irgendwelcher Code von und bei mir nicht so
funktioniert, wie gewünscht, was nun mit ganz hoher
Wahrscheinlichkeit auch an diesem Code liegen kann.

Auf der anderen Seite ist das aber einfach ein Thema,
das neu für mich ist, so daß ich da einfach zu wenig
Erfahrungswerte bzgl. realer Hardware habe (und
im Zweifel ist letztere ja auch nur so sorgfältig
gestaltet, daß "Fehler" nicht so auffallen).


Also ich stelle mal unten das wichtigste vom Code
dazu, dann ist das nicht so abstrakt. Die Idee war,
für eine (grosse) Sammlung von Objekten Threadlocks
zur Verfügung zu stellen, also eine "freiwillige",
Möglichkeit für Threads, jeweils exclusiv Zugriff
zu Objekten zu erhalten (mit dem Risiko, beim
"Antrag" erstmal eingeschläfert zu werden).

Dazu gibt's für jedes Objekt ein int32, das über
Compare-and-Swap Operationen mit Informationen hält:
zu Lock-holder, Lock-count (ein Thread bzw.
AccessPoint-Object darf das Objekt mehrfach locken),
sowie einen Schlüssel zu Informationen über
auf das Objekt wartende AccessPoints.

Im Prinzip scheints zu funktionieren, aber so etwa
einmal pro 1Mio. Lock-Operationen sieht es
zumindest symptomatisch so aus, als würde die
Compare-and-Swap Operation unerlaubt swappen (der
erste wartende Thread wird korrekt geweckt, hat aber
das Lock dann gar nicht, und bekommt es auch nicht
mehr).

Also eh' ich jetzt noch weiter rumlaber, kippe
ich mal den Code ab. Vielleicht hat ja wer 'ne Idee
(Barrieren um die InterlockedOPs habe ich schon
probiert, obwohl die Massenahme nicht gut zur
Symptomatik passt).

Gruss

Jan bruns






procedure TparlocCol.lockObj(o : Toid; ap : TparlocAP);
var ap2 : TparlocAP; a, wc, old : longint; lv : Plongint;
begin
RTLeventResetEvent(ap.locksig);
lv := locate_locvar(o);
repeat
// assume there currently is no lock
a := (ap.id shl lsb_lock_holder) + 1;
old := InterlockedCompareExchange(lv^,a,0);
if (old=0) then break
else begin
a := (old shr lsb_lock_holder) and apidmask;
if (a = ap.id) then begin
{ we already have the lock. just inc. }
a := old and lockcountmask;
if (a>=lockcountlimit) then begin
raise parlocAPexcpt.Create('Too many locks on object.');
end else begin
a := InterlockedCompareExchange(lv^,old+1,old);
if (a=old) then break;
end;
end else begin
{ another AP has the lock. try linking into
the chain of waiters. }
wc := (old shr lsb_lock_waiter) and apidmask;
if (wc=0) then begin
wc := start_new_waitchain(o,ap);
a := old or (wc shl lsb_lock_waiter);
a := InterlockedCompareExchange(lv^,a,old);
if (a=old) then begin
unlock_waitchain(wc);
wait_waitchain(wc,o,ap);
break;
end else discard_waitchain(wc); // and retry
end else begin
if try_append_waitchain(wc,o,ap) then begin
wait_waitchain(wc,o,ap);
break;
end; // else retry
end;
end;
end;
until false;
end;

procedure TparlocCol.unlockObj(o : Toid; ap : TparlocAP);
var ap2 : TparlocAP; a, old, wc, wc2 : longint; lv : Plongint;
begin
lv := locate_locvar(o);
repeat
// assume we had a single lock with no waiters
a := (ap.id shl lsb_lock_holder) + 1;
old := InterlockedCompareExchange(lv^,0,a);
if not(old=a) then begin
a := (old shr lsb_lock_holder) and apidmask;
if (a=ap.id) then begin
a := old and lockcountmask;
if (a>1) then begin
// we had locked the object more than 1 time
InterLockedDecrement(lv^);
break;
end else if (a=1) then begin
{ give the lock to the first waiter. }
wc := (old shr lsb_lock_waiter) and apidmask;
if (wc=0) then begin
raise parlocAPexcpt.Create('No waiters or not?');
end else begin
lock_waitchain(wc); // forced, waited
ap2 := get_first_waiter(wc); // no remove
wc2 := decide_keep_waitchain(wc); // wc, or 0, if waiting<2
a := (ap2.id shl lsb_lock_holder);
a := a or (wc2 shl lsb_lock_waiter);
a := a +1;
a := InterlockedCompareExchange(lv^,a,old);
if not(a=old) then begin
raise parlocAPexcpt.Create('Unexpected lockvar mod during unlock.');
end else begin
if (wc2=0) then begin
discard_waitchain(wc);
end else begin
remove_first_waiter(wc);
unlock_waitchain(wc);
end;
RTLeventSetEvent(ap2.locksig); // wake up the oldest waiting thread
break;
end;
end;
end else begin
raise parlocAPexcpt.Create('Unclean reach of lockcnt=0.');
end;
end else begin
raise parlocAPexcpt.Create('Non-Owner attempt to unlock.');
end;
end else break; // initial assumption correct
until false;
end;











Bernhard Schornak

unread,
Dec 4, 2014, 8:57:20 AM12/4/14
to
Jan Bruns schrieb:
<schnipp>

Mit Sicherheit weder x86 noch 68k Opcodes. Auch HLA oder
RosAsm schaut anders aus. Gibt es auch einen Link zu dem
"Assembler", der mit solch einer merkwürdig formatierten
Mischung aus Text und Hokuspokus etwas anfangen kann?

Zum Thema gibt es grundlegend

http://de.wikipedia.org/wiki/Cache-Koh%C3%A4renz

und vertiefend Kapitel 7.3 in AMDs "AMD64 Architecture
Programmer’s Manual, Volume 2: System Programming" oder
"Intel 64 and IA-32 Architectures Software Developer’s
Manual", Volume 3a, Kapitel 11.

Aus diesen Dokumenten geht eindeutig hervor, dass x86-
Programmierer nicht direkten Einfluss auf die Kohärenz
der diversen Cachehierarchien nehmen können. Auch 68k-
Systeme mit mehreren Prozessoren dürften die möglichen
Kohärenz-Probleme mit einer hardwareseitigen Steuerung
über ihren Chipsatz lösen, da softwareseitige Lösungen
viel zu träge wären, um derlei Aufgaben in Echtzeit zu
erledigen. Eine softwareseitige Lösung könnte nur über
MSRs (Machine State Register) realisiert werden. Diese
müssten von allen Prozessoren ansprechbar sein, was zu
reichlich komplexen Verwaltungsstrukturen - mit daraus
resultierender Entschleunigung - führen würde. Heutige
MSRs haben Zugriffszeiten von zwei- oder dreistelligen
Taktzyklen. Je nach dem, wie viele Prozessoren auf ein
MSR zugreifen, erhöht sich die Zugriffszeit drastisch.
Die interne Lösung regelt das Problem in wenigen Takt-
zyklen. Sie ist für System- und Anwendungsprogramierer
zudem transparent.


Grüsse aus Augsburg

Bernhard Schornak

Jan Bruns

unread,
Dec 4, 2014, 3:50:15 PM12/4/14
to

Bernhard Schornak:
> Jan Bruns schrieb:

> Mit Sicherheit weder x86 noch 68k Opcodes. Auch HLA oder RosAsm schaut
> anders aus. Gibt es auch einen Link zu dem "Assembler", der mit solch
> einer merkwürdig formatierten Mischung aus Text und Hokuspokus etwas
> anfangen kann?

Eingesetzter Compiler war http://freepascal.org

Der gezeigte Code besteht ja fast ausschliesslich
aus Calls. Die hier wichtigsten (Interlocked*)
Operationen wurden für AMD64 ebenfalls in calls
übersetzt, und zwar zur "System-Unit" des Compilers
(dort bspw. mit "lock cmpxchg" umgesetzt).
Möglicherweise aus Rücksichtnahme auf Zielsysteme,
bei denen diese Operationen nicht mit Einzel-
instruktionen umzusetzen sind. Weiter tauchen
mit (RTLevent*) einige in OS-calls übersetzte
Aufrufe auf, sowie überwiegend Aufrufe zu weiteren,
nicht gezeigten Methoden des Objekts.

Was die Formatierung betrifft (sofern die bei
Dir richtig angezeigt wurde, im Zitat er scheint
die jedenfalls korrekt): Die hat tatsächlich eine
ungewöhnlich ausgeprägte persönliche Note, folgt
aber einem ausgetüfteltem System, das ist
zweckmässig so.

> Zum Thema gibt es grundlegend
> http://de.wikipedia.org/wiki/Cache-Koh%C3%A4renz

Kenne ich. Also nicht so auswendig, daß diese
ganzen Begriffe mit all ihren Implikationen jederzeit
voll präsent wären, aber ich habe z.B. in 'nem FPGA
schon einen (unicore) Cache implementiert.

> und vertiefend Kapitel 7.3 in AMDs "AMD64 Architecture Programmer’s
> Manual, Volume 2: System Programming" oder "Intel 64 and IA-32
> Architectures Software Developer’s Manual", Volume 3a, Kapitel 11.

Aus diesen Dokumenten geht hervor, daß im Sinne
meiner Fragestellung eine ganz und gar absolute
Cache-Kohärenz zu den Idealen der CPU-Entwickler
zählt. Hast Du vielleicht auch noch einen Link
auf die Bug-Report Liste zur Wald-und-Wiesen-CPU?

> Aus diesen Dokumenten geht eindeutig hervor, dass x86- Programmierer
> nicht direkten Einfluss auf die Kohärenz der diversen Cachehierarchien
> nehmen können.
> Auch 68k- Systeme mit mehreren Prozessoren dürften die
> möglichen Kohärenz-Probleme mit einer hardwareseitigen Steuerung über
> ihren Chipsatz lösen, da softwareseitige Lösungen viel zu träge wären,
> um derlei Aufgaben in Echtzeit zu erledigen.

Äh. User-Land und "Einfluss auf die Cache Kohärenz"
sind doch nun wirklich Begriffe, denen man auch
intuitiv kein Zusammenpassen andeutet.

Gruss

Jan Bruns


Bernhard Schornak

unread,
Dec 4, 2014, 6:09:28 PM12/4/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>> Jan Bruns schrieb:
>
>> Mit Sicherheit weder x86 noch 68k Opcodes. Auch HLA oder RosAsm schaut
>> anders aus. Gibt es auch einen Link zu dem "Assembler", der mit solch
>> einer merkwürdig formatierten Mischung aus Text und Hokuspokus etwas
>> anfangen kann?
>
> Eingesetzter Compiler war http://freepascal.org
>
> Der gezeigte Code besteht ja fast ausschliesslich
> aus Calls. Die hier wichtigsten (Interlocked*)
> Operationen wurden für AMD64 ebenfalls in calls
> übersetzt, und zwar zur "System-Unit" des Compilers
> (dort bspw. mit "lock cmpxchg" umgesetzt).
> Möglicherweise aus Rücksichtnahme auf Zielsysteme,
> bei denen diese Operationen nicht mit Einzel-
> instruktionen umzusetzen sind. Weiter tauchen
> mit (RTLevent*) einige in OS-calls übersetzte
> Aufrufe auf, sowie überwiegend Aufrufe zu weiteren,
> nicht gezeigten Methoden des Objekts.
>
> Was die Formatierung betrifft (sofern die bei
> Dir richtig angezeigt wurde, im Zitat er scheint
> die jedenfalls korrekt): Die hat tatsächlich eine
> ungewöhnlich ausgeprägte persönliche Note, folgt
> aber einem ausgetüfteltem System, das ist
> zweckmässig so.


Davon ging ich aus. Assemblercode schaut - nichtsdestotrotz -
etwas anders aus: http://tinyurl.com/oza4fdz (AT&T-Dialekt).

Noch zweckmässiger wäre es daher doch, das in einer Pascal-NG
zu posten? Hier in d.c.l.a ist zwar nicht gar so viel los wie
in a.l.asm oder c.l.a.x86, das heisst aber nicht, dass irgend
einen Leser in Assembler-NGs HLL-Code wirklich interessiert.

Möglicherweise wärest Du mit "selbstgestrickten" Cachestrate-
gien in alt.os.development besser aufgehoben?


>> Zum Thema gibt es grundlegend
>> http://de.wikipedia.org/wiki/Cache-Koh%C3%A4renz
>
> Kenne ich. Also nicht so auswendig, daß diese
> ganzen Begriffe mit all ihren Implikationen jederzeit
> voll präsent wären, aber ich habe z.B. in 'nem FPGA
> schon einen (unicore) Cache implementiert.


Schön für Dich! ;)


>> und vertiefend Kapitel 7.3 in AMDs "AMD64 Architecture Programmer’s
>> Manual, Volume 2: System Programming" oder "Intel 64 and IA-32
>> Architectures Software Developer’s Manual", Volume 3a, Kapitel 11.
>
> Aus diesen Dokumenten geht hervor, daß im Sinne
> meiner Fragestellung eine ganz und gar absolute
> Cache-Kohärenz zu den Idealen der CPU-Entwickler
> zählt. Hast Du vielleicht auch noch einen Link
> auf die Bug-Report Liste zur Wald-und-Wiesen-CPU?


Welche da wäre? Ich bezweifle, das es nur eine einzige gibt!


>> Aus diesen Dokumenten geht eindeutig hervor, dass x86- Programmierer
>> nicht direkten Einfluss auf die Kohärenz der diversen Cachehierarchien
>> nehmen können.
>> Auch 68k- Systeme mit mehreren Prozessoren dürften die
>> möglichen Kohärenz-Probleme mit einer hardwareseitigen Steuerung über
>> ihren Chipsatz lösen, da softwareseitige Lösungen viel zu träge wären,
>> um derlei Aufgaben in Echtzeit zu erledigen.
>
> Äh. User-Land und "Einfluss auf die Cache Kohärenz"
> sind doch nun wirklich Begriffe, denen man auch
> intuitiv kein Zusammenpassen andeutet.


Was wolltest Du mit dieser Aneinanderreihung vieler komplexer
Worte zu einem noch komplexeren Satzbau eigentlich mitteilen?

Jan Bruns

unread,
Dec 4, 2014, 10:18:16 PM12/4/14
to
Hallo.

Übrigens, der Code scheint zu funktionieren (soweit
ich das testen konnte), wenn ich den wie unten gezeigt
so abändere, daß lockObj() nur von einem Kern
ausgeführt wird (unlockObj() unverändert).

Ein Zusammenhang mit meinen Datenstrukturen zum
Handling der "waitchain" scheint unwahrscheinlich,
weil der Fehler wieder auftaucht, wenn ich die
critical section auf den Bereich "another AP
has the lock" beschränke.

Anscheinend müssen eher die Interlocked*
Operationen single-core sein. Warum wohl?

Gruss

Jan Bruns




procedure TparlocCol.lockObj(o : Toid; ap : TparlocAP);
var ap2 : TparlocAP; a, wc, old : longint; lv : Plongint;
begin
RTLeventResetEvent(ap.locksig);
lv := locate_locvar(o);
enter_cs;
leave_cs;
wait_waitchain(wc,o,ap);
exit;
end else discard_waitchain(wc); // and retry
end else begin
if try_append_waitchain(wc,o,ap) then begin
leave_cs;
wait_waitchain(wc,o,ap);
exit;
end; // else retry
end;
end;
end;
until false;
leave_cs;
end;

Jan Bruns

unread,
Dec 5, 2014, 4:13:00 AM12/5/14
to

Bernhard Schornak:
> Jan Bruns schrieb:


> Möglicherweise wärest Du mit "selbstgestrickten" Cachestrate- gien in
> alt.os.development besser aufgehoben?

Sehr witzig.

Welche Plattformunabhängigen, real vorhandenen Betriebssystemcall
schlägst Du denn vor, um bspw. 1 Mio. Objekte mit Threadlocks zu versehen?


>> Aus diesen Dokumenten geht hervor, daß im Sinne meiner Fragestellung
>> eine ganz und gar absolute Cache-Kohärenz zu den Idealen der
>> CPU-Entwickler zählt. Hast Du vielleicht auch noch einen Link auf die
>> Bug-Report Liste zur Wald-und-Wiesen-CPU?

> Welche da wäre? Ich bezweifle, das es nur eine einzige gibt!

Hardware hat genau wie Software immer irgendwelche Bugs.

Dieses Problem hier hat allerdings anscheinend eine andere Ursache,
die bereits dokumentiert ist:

Ich glaube, die Ursache des Problems ist folgende:

CMPXCHG schreibt laut irgendeinem Datenblatt von
AMD oder Intel auf jeden Fall, entweder die
glesenen Daten, oder den Registerwert.

Nun ist da aber auch ein Memory-System, bei
es normal ist, daß bei gleichzeitigen Schreib-
anforderungen von mehreren Seiten nur eine Seite
endgültig geschrieben haben kann.

Wenn dann auf mehreren Kernen gleichzeitig
CMPXCHG ausgeführt wird, und beide auf jeden
Fall schreiben, obwohl nur einer konsistente
Daten liefert, wird sich das Memory-System
regelmässig für die falschen (unveränderten)
Daten entscheiden.

Gruss

Jan Bruns


Bernhard Schornak

unread,
Dec 5, 2014, 11:43:04 AM12/5/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>> Jan Bruns schrieb:
>
>> Möglicherweise wärest Du mit "selbstgestrickten" Cachestrate- gien in
>> alt.os.development besser aufgehoben?
>
> Sehr witzig.


Das war (und ist!) durchaus ernst gemeint. Du postest den
Code ja nicht, weil es Dir gerade langweilig ist, sondern
um Dein Wissen mit anderen Menschen zu teilen. In AOD be-
steht immerhin die Möglichkeit, dass sich ein anderer OS-
Entwickler ebenfalls mit Cacheverwaltung beschäftigt, und
seine Erfahrungen gegebenenfalls mit Dir austauscht.


> Welche Plattformunabhängigen, real vorhandenen Betriebssystemcall
> schlägst Du denn vor, um bspw. 1 Mio. Objekte mit Threadlocks zu versehen?


Für Assemblerprogrammierer gibt es ja seit Ewigkeiten den
LOCK-Präfix. Wie es in so genannten "Hochsprachen" gelöst
wird, hängt von der jeweiligen Hochsprache ab. Das könnte
-hier- allerdings nur von Interesse sein, wenn es sich um
eine in Assembler verfasste Funktion / Routine handelte -
Lösungen in Hochsprachen sind nur möglich, wenn diese wie
C eine Möglichkeit bieten, Assemblerbefehle direkt in den
Hochsprachencode einzubinden. Was übrigens den Sinn einer
Hochsprache, nämlich die Unabhängigkeit von der Maschine,
auf der sie gerade läuft, ad absurdum führt...


>>> Aus diesen Dokumenten geht hervor, daß im Sinne meiner Fragestellung
>>> eine ganz und gar absolute Cache-Kohärenz zu den Idealen der
>>> CPU-Entwickler zählt. Hast Du vielleicht auch noch einen Link auf die
>>> Bug-Report Liste zur Wald-und-Wiesen-CPU?
>
>> Welche da wäre? Ich bezweifle, das es nur eine einzige gibt!
>
> Hardware hat genau wie Software immer irgendwelche Bugs.


Das beantwortet die Frage nicht. Da Du die Existenz einer
"Wald-und-Wiesen-CPU" deklarierst, solltest Du Hersteller
und Typbezeichnung doch jederzeit benennen können.

Es gibt sowohl von AMD als auch von iNTEL dicke PDFs, die
Listen mit allen bekannten Fehlern und "Workarounds" ent-
halten.

Das "Perfekte an und für sich" ist eine Illusion -dummer-
Menschen, die mangels Denkvermögen nicht erfassen können,
dass etwas "perfektes" in einem sich selbst entwickelnden
Universum schon prinzipbedingt nicht existieren kann. Was
auch entwickelt wird - es gibt immer eine Möglickeit, das
aktuelle Modell noch weiter zu verbessern.


> Dieses Problem hier hat allerdings anscheinend eine andere Ursache,
> die bereits dokumentiert ist:
>
> Ich glaube, die Ursache des Problems ist folgende:
>
> CMPXCHG schreibt laut irgendeinem Datenblatt von
> AMD oder Intel auf jeden Fall, entweder die
> glesenen Daten, oder den Registerwert.
>
> Nun ist da aber auch ein Memory-System, bei
> es normal ist, daß bei gleichzeitigen Schreib-
> anforderungen von mehreren Seiten nur eine Seite
> endgültig geschrieben haben kann.
>
> Wenn dann auf mehreren Kernen gleichzeitig
> CMPXCHG ausgeführt wird, und beide auf jeden
> Fall schreiben, obwohl nur einer konsistente
> Daten liefert, wird sich das Memory-System
> regelmässig für die falschen (unveränderten)
> Daten entscheiden.


Im von Dir vorgegebenen Szenario -können- die Prozessoren
nur unveränderte Daten lesen, da Änderungen erst nach der
vorgenommenen Manipulation an die Speicherhierarchie (vom
L1-Cache bis hin zum Hauptspeicher) weitergegeben werden.
Deshalb wurde ja der LOCK-Befehl eingeführt. Er wirkt auf
den Datenbus des Systems, und sperrt alle Prozessoren bis
auf einen, so lange ein R-M-W-Schreibzugriff erfolgt. Was
auf der Kostenseite (da Gewinn[x] = Verlust[y]) R-M-W-Zu-
griffe für alle Prozessoren verlangsamt.

Wer verwendet schon freiwillig CMPXCHG? In derselben Zeit
können parallel (abhängig von der Zahl der Pipes) mehrere
MOV-CMP-MOV-Operationen ausgeführt werden.

Jan Bruns

unread,
Dec 5, 2014, 3:20:31 PM12/5/14
to

Bernhard Schornak:
> Jan Bruns schrieb:

>>> Möglicherweise wärest Du mit "selbstgestrickten" Cachestrate- gien in
>>> alt.os.development besser aufgehoben?
>
>> Sehr witzig.

> Das war (und ist!) durchaus ernst gemeint. Du postest den Code ja nicht,
> weil es Dir gerade langweilig ist, sondern um Dein Wissen mit anderen
> Menschen zu teilen. In AOD be- steht immerhin die Möglichkeit, dass sich
> ein anderer OS- Entwickler ebenfalls mit Cacheverwaltung beschäftigt,
> und seine Erfahrungen gegebenenfalls mit Dir austauscht.


Was denn für Wissen?
Nö, ich habe den Code wie gesagt abgekippt, um den Kontext der
Fragestellung nach dem Verhalten moderner CPU zu veranschaulichen.

Und "Cacheverwaltung"? Was ist das?

Das Anwendungsbeispiel für den (so ja nicht sinnvoll funktionieren
Code) wäre sowas wie eine Datenbank, deren Datenelemente von mehren
Prozessorkernen gleichzeitig beabreitet werden könnten. Dazu müssen
der Kerne sich irgendwie absprechen, damit sich nicht auf halbfertige
Daten verlassen werden muss.


> Für Assemblerprogrammierer gibt es ja seit Ewigkeiten den LOCK-Präfix.
> Wie es in so genannten "Hochsprachen" gelöst wird, hängt von der
> jeweiligen Hochsprache ab.

Ich habe aber doch schon gesagt, daß es sich eifach um ganz
stinkpiefnormale x86 calls zu stimkoefnormalen x86 Unterfunktionen
handelt:

Zum Beispiel eine Ausgabe vom linux tool "perf":

: Disassembly of section .text:
:
: 0000000000410f88 <FPC_INTERLOCKEDCOMPAREEXCHANGE>:
1,60 : 410f88: push %rbp
9,29 : 410f89: mov %rsp,%rbp
1,28 : 410f8c: sub $0x10,%rsp
3,85 : 410f90: mov %edx,%eax
0,96 : 410f92: lock cmpxchg %esi,(%rdi)
83,01 : 410f96: leaveq


Mit dem Lock-Präfix habe ich bisher noch nie zu tun gehabt, das schien
mir bisher auch hauptsächlich ein Relikt aus der ISA-Bus Ära zu sein, und
bisher wollte ich einfach noch kein #LOCK-Signal.

Dem Anschein nach bewirkt es nicht wirklich zuverlässig das, was andere
Leute sich davon zu erhoffen scheinen (etwa das, was ich von der gerade
gezeigten INTERLOCKEDCOMPAREEXCHANGE erhofft habe, eben eine vollständig
atomische Operation auch in dem Sinne, daß deren Wirkung von allen Kernen
aus gleich aussieht, und der caller zuverlässig entscheiden kann, was
andere Kerne durch diie Operation zu sehen bekommen).

> Das könnte -hier- allerdings nur von
> Interesse sein, wenn es sich um eine in Assembler verfasste Funktion /
> Routine handelte - Lösungen in Hochsprachen sind nur möglich, wenn diese
> wie C eine Möglichkeit bieten, Assemblerbefehle direkt in den
> Hochsprachencode einzubinden. Was übrigens den Sinn einer Hochsprache,
> nämlich die Unabhängigkeit von der Maschine, auf der sie gerade läuft,
> ad absurdum führt...

Naja, im Zweifel geht ja auf jeden Fall serialisieren, also
den ganzen Kram mit nur einem Kern erledigen. Genau das wollte ich aber
ja eigentlich vermeiden.


> Es gibt sowohl von AMD als auch von iNTEL dicke PDFs, die Listen mit
> allen bekannten Fehlern und "Workarounds" ent- halten.

Tatsächlich? Interessant. Wo?



>> CMPXCHG schreibt laut irgendeinem Datenblatt von AMD oder Intel auf
>> jeden Fall, entweder die glesenen Daten, oder den Registerwert.
>>
>> Nun ist da aber auch ein Memory-System, bei es normal ist, daß bei
>> gleichzeitigen Schreib- anforderungen von mehreren Seiten nur eine
>> Seite endgültig geschrieben haben kann.
>>
>> Wenn dann auf mehreren Kernen gleichzeitig CMPXCHG ausgeführt wird, und
>> beide auf jeden Fall schreiben, obwohl nur einer konsistente Daten
>> liefert, wird sich das Memory-System regelmässig für die falschen
>> (unveränderten) Daten entscheiden.

Leteres solle aber ja eigentlich, wie Du schriebst, und wie auch viele
andere meinen, durch das Lock-Präfix vermieden werden.

> Im von Dir vorgegebenen Szenario -können- die Prozessoren nur
> unveränderte Daten lesen, da Änderungen erst nach der vorgenommenen
> Manipulation an die Speicherhierarchie (vom L1-Cache bis hin zum
> Hauptspeicher) weitergegeben werden. Deshalb wurde ja der LOCK-Befehl
> eingeführt. Er wirkt auf den Datenbus des Systems, und sperrt alle
> Prozessoren bis auf einen, so lange ein R-M-W-Schreibzugriff erfolgt.
> Was auf der Kostenseite (da Gewinn[x] = Verlust[y]) R-M-W-Zu- griffe für
> alle Prozessoren verlangsamt.

Bus? Sehe ich nicht. Die Zeiten, in denen das Spass gemacht haben kann,
sich in Datenblättern die Funktion einzelner Pins anzusehen jeweils
aktueller CPUs anusehen, sind ja erstmal vorbei.

> Wer verwendet schon freiwillig CMPXCHG? In derselben Zeit können
> parallel (abhängig von der Zahl der Pipes) mehrere
> MOV-CMP-MOV-Operationen ausgeführt werden.

Klingt jetzt erstmal nach serialisieren. Z.B. könne ich eine ObjektId
(Toid) dazu verwenden, eine critical section, oder sowas auszuwählen,
damit die Kerne sich seltener gegenseitig aufhalten.

Angenehm wäre mir allerdings, wenn sich dieses unerwartete LOCK CMPXCHG
Verhalten (so es nicht an irgendwelchen sonstigen Fehlern lag)
aufklären täte. Ich könnte ja problemlos damit leben, da eben
falsche Erwartungen gehabt zu haben, nur wo, das wäre dann schon
interessant. Hat mich immerhin schon einige Stunden gekostet, mir
dieses compare-and-swap basierte System auszudenken.

Gruss

Jan Bruns






Peter J. Holzer

unread,
Dec 6, 2014, 2:32:27 AM12/6/14
to
On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
> Wer verwendet schon freiwillig CMPXCHG?

Leute, die Locking-Primitives schreiben?

> In derselben Zeit können parallel (abhängig von der Zahl der Pipes)
> mehrere MOV-CMP-MOV-Operationen ausgeführt werden.

Damit bekommst Du ein race-condition-freies Locking-Primitive hin?

Ich will nicht ausschließen, dass das theoretisch möglich ist, aber ich
glaube doch, dass sich die Intel-Leute was dabei gedacht haben, als sie
(mit dem 486er?) CMPXCHG eingeführt haben.

hp


--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel

Peter J. Holzer

unread,
Dec 6, 2014, 2:40:17 AM12/6/14
to
On 2014-12-05 03:18, Jan Bruns <eb...@abnuto.de> wrote:
> Übrigens, der Code scheint zu funktionieren (soweit
> ich das testen konnte), wenn ich den wie unten gezeigt
> so abändere, daß lockObj() nur von einem Kern
> ausgeführt wird (unlockObj() unverändert).
>
> Ein Zusammenhang mit meinen Datenstrukturen zum
> Handling der "waitchain" scheint unwahrscheinlich,
> weil der Fehler wieder auftaucht, wenn ich die
> critical section auf den Bereich "another AP
> has the lock" beschränke.
>
> Anscheinend müssen eher die Interlocked*
> Operationen single-core sein. Warum wohl?

Ich habe eher den Verdacht, dass Du irgendwo im waitchain-Handling einen
Fehler hast. Den Code verstehe ich nämlich nicht, soweit Du ihn gezeigt
hast (ein paar Kommentare im Code würden wirklich nicht schaden), und
den Inhalt der Funktionen hast Du nicht gezeigt.

Dadurch, dass Du lockObj auf eine CPU zwingst, läuft auch das ganze
waitchain-Handling nur mehr auf einer CPU und damit seriell.

Das cmpxchng auf Deinem System (CPU+Memory-Controller) buggy ist, kann
man zwar nicht 100% ausschließen, ist aber doch ziemlich
unterschiedlich. Das würde nämlich jedes Betriebssystem und jede
Multithreading-Library (und jedes Programm, das sie verwendet),
ebenfalls betreffen.

Jan Bruns

unread,
Dec 6, 2014, 2:44:58 AM12/6/14
to
Jan Bruns:

> if try_append_waitchain(wc,o,ap) then begin

Ah! Das Ding hat nicht beachtet, daß diese waitchains nicht nur schon
längst abgearbeitet sein können, sondern auch bereits recycelt.

Die Welt braucht dringend mehr Überrundungszähler.

Also kann ich jetzt über Optimierungen nachdenken.
Momentan sehe ich so bestenfalls ca. 4 Mio. Lock Operationen pro
Sekunde (auf AMD-350, lowcost Laptop CPU). Das ist eigentlich auch
schon, was ich mir ursprünglich auch ausgemalt hatte, kann ja
so nur nur noch besser gehen.

Jedenfalls sieht es so aus, als würde die CPU so funktionieren,
wie anfangs gedacht, ohne irgendwelche derart leicht zu findende
Kohärenz-Fehler. Wunderbar.

Gruss

Jan Bruns


Bernhard Schornak

unread,
Dec 6, 2014, 6:13:32 AM12/6/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>> Jan Bruns schrieb:
>
>>>> Möglicherweise wärest Du mit "selbstgestrickten" Cachestrate- gien in
>>>> alt.os.development besser aufgehoben?
>>
>>> Sehr witzig.
>
>> Das war (und ist!) durchaus ernst gemeint. Du postest den Code ja nicht,
>> weil es Dir gerade langweilig ist, sondern um Dein Wissen mit anderen
>> Menschen zu teilen. In AOD be- steht immerhin die Möglichkeit, dass sich
>> ein anderer OS- Entwickler ebenfalls mit Cacheverwaltung beschäftigt,
>> und seine Erfahrungen gegebenenfalls mit Dir austauscht.
>
>
> Was denn für Wissen?


Das, das Du Dir bei der Entwicklung des geposteten Texts ange-
eignet hast?


> Nö, ich habe den Code wie gesagt abgekippt, um den Kontext der
> Fragestellung nach dem Verhalten moderner CPU zu veranschaulichen.


Dazu musstest Du Dich aber -irgendwann einmal- mit dem Problem
auseinandersetzen?


> Und "Cacheverwaltung"? Was ist das?


Alles, was mit der Verwaltung der Caches zu tun hat - z.B. das
MESI/MOESI-Protokoll, die Befehle CLFLUSH, INVD, WBINDV, Hints
wie MOVNTDQ, und so weiter...


> Das Anwendungsbeispiel für den (so ja nicht sinnvoll funktionieren
> Code) wäre sowas wie eine Datenbank, deren Datenelemente von mehren
> Prozessorkernen gleichzeitig beabreitet werden könnten. Dazu müssen
> der Kerne sich irgendwie absprechen, damit sich nicht auf halbfertige
> Daten verlassen werden muss.


Das kann ich leider nicht nachvollziehen, da Dein merkwürdiger
Text keine einzige Zeile Assemblercode enthält. Wie gesagt: Du
schreibst in einer NG, die sich an Assemblerprogrammierer (und
nicht an Hochsprachenfreaks...) richtet.


>> Für Assemblerprogrammierer gibt es ja seit Ewigkeiten den LOCK-Präfix.
>> Wie es in so genannten "Hochsprachen" gelöst wird, hängt von der
>> jeweiligen Hochsprache ab.
>
> Ich habe aber doch schon gesagt, daß es sich eifach um ganz
> stinkpiefnormale x86 calls zu stimkoefnormalen x86 Unterfunktionen
> handelt:
>
> Zum Beispiel eine Ausgabe vom linux tool "perf":
>
> : Disassembly of section .text:
> :
> : 0000000000410f88 <FPC_INTERLOCKEDCOMPAREEXCHANGE>:
> 1,60 : 410f88: push %rbp
> 9,29 : 410f89: mov %rsp,%rbp
> 1,28 : 410f8c: sub $0x10,%rsp
> 3,85 : 410f90: mov %edx,%eax
> 0,96 : 410f92: lock cmpxchg %esi,(%rdi)
> 83,01 : 410f96: leaveq


Was sich auf

mov %edx, %eax
lock cmpxchg %esi, (%rdi)
ret

reduzieren liesse. Der Rest ist redundant, da die einzige hier
ausgeführte Sequenz keinen Stapelrahmen (stackframe) benötigt.
Die verwendeten Register sind laut "64 Bit Calling Convention"
der Linux-API als "volatile" definiert, sie müssen somit nicht
gesichert und wieder hergestellt werden. Bei Windows-64 müsste
man RDI und RSI sichern. Es geht auch ganz ohne Stapelrahmen:

http://tinyurl.com/oxwepcr


> Mit dem Lock-Präfix habe ich bisher noch nie zu tun gehabt, das schien
> mir bisher auch hauptsächlich ein Relikt aus der ISA-Bus Ära zu sein, und
> bisher wollte ich einfach noch kein #LOCK-Signal.


http://www.i8086.de/asm/8086-88-asm-lock.html


> Dem Anschein nach bewirkt es nicht wirklich zuverlässig das, was andere
> Leute sich davon zu erhoffen scheinen (etwa das, was ich von der gerade
> gezeigten INTERLOCKEDCOMPAREEXCHANGE erhofft habe, eben eine vollständig
> atomische Operation auch in dem Sinne, daß deren Wirkung von allen Kernen
> aus gleich aussieht, und der caller zuverlässig entscheiden kann, was
> andere Kerne durch diie Operation zu sehen bekommen).


Genaue Informationen könntest Du über das verwendete Protokoll,
MESI bei iNTEL / MOESI bei AMD, erfahren. Diese Protokolle sind
für die Kommunikation zwischen den Kernen verantwortlich.


>> Das könnte -hier- allerdings nur von
>> Interesse sein, wenn es sich um eine in Assembler verfasste Funktion /
>> Routine handelte - Lösungen in Hochsprachen sind nur möglich, wenn diese
>> wie C eine Möglichkeit bieten, Assemblerbefehle direkt in den
>> Hochsprachencode einzubinden. Was übrigens den Sinn einer Hochsprache,
>> nämlich die Unabhängigkeit von der Maschine, auf der sie gerade läuft,
>> ad absurdum führt...
>
> Naja, im Zweifel geht ja auf jeden Fall serialisieren, also
> den ganzen Kram mit nur einem Kern erledigen. Genau das wollte ich aber
> ja eigentlich vermeiden.


Mit LOCK CMPXCHG(x) dauert es wesentlich länger, die selbe Auf-
gabe abzuarbeiten, da alle am Bus hängenden Prozessoren auf die
Abarbeitung aller signalisierten LOCKs warten müssen.


>> Es gibt sowohl von AMD als auch von iNTEL dicke PDFs, die Listen mit
>> allen bekannten Fehlern und "Workarounds" ent- halten.
>
> Tatsächlich? Interessant. Wo?


Revision Guide for AMD Family 10h Processors PDF: 41322
Revision Guide for AMD Family 15h Models 00h-0Fh
Processors PDF: 48063

Bei iNTEL hab ich noch keine vergleichbaren Dokumente gefunden.


>>> CMPXCHG schreibt laut irgendeinem Datenblatt von AMD oder Intel auf
>>> jeden Fall, entweder die glesenen Daten, oder den Registerwert.
>>>
>>> Nun ist da aber auch ein Memory-System, bei es normal ist, daß bei
>>> gleichzeitigen Schreib- anforderungen von mehreren Seiten nur eine
>>> Seite endgültig geschrieben haben kann.
>>>
>>> Wenn dann auf mehreren Kernen gleichzeitig CMPXCHG ausgeführt wird, und
>>> beide auf jeden Fall schreiben, obwohl nur einer konsistente Daten
>>> liefert, wird sich das Memory-System regelmässig für die falschen
>>> (unveränderten) Daten entscheiden.
>
> Leteres solle aber ja eigentlich, wie Du schriebst, und wie auch viele
> andere meinen, durch das Lock-Präfix vermieden werden.


LOCK sperrt die Kommunikation für alle am Bus hängenden Geräte,
bis der die Sperrung auslösende Befehl abgearbeitet wurde.


>> Im von Dir vorgegebenen Szenario -können- die Prozessoren nur
>> unveränderte Daten lesen, da Änderungen erst nach der vorgenommenen
>> Manipulation an die Speicherhierarchie (vom L1-Cache bis hin zum
>> Hauptspeicher) weitergegeben werden. Deshalb wurde ja der LOCK-Befehl
>> eingeführt. Er wirkt auf den Datenbus des Systems, und sperrt alle
>> Prozessoren bis auf einen, so lange ein R-M-W-Schreibzugriff erfolgt.
>> Was auf der Kostenseite (da Gewinn[x] = Verlust[y]) R-M-W-Zu- griffe für
>> alle Prozessoren verlangsamt.
>
> Bus? Sehe ich nicht. Die Zeiten, in denen das Spass gemacht haben kann,
> sich in Datenblättern die Funktion einzelner Pins anzusehen jeweils
> aktueller CPUs anusehen, sind ja erstmal vorbei.


Einen Prozessor mit Null Pins und ohne interne Verdrahtung gibt
es (noch) nicht...

Gemeint ist hier auch eher der interne Bus, an dem alle "Kerne"
eines Prozessors hängen. Über diesen werden alle Kerne an ihren
Anteil des L2- und L3-Cache und den Hauptspeicher angeschlossen
und kommunizieren miteinander.


>> Wer verwendet schon freiwillig CMPXCHG? In derselben Zeit können
>> parallel (abhängig von der Zahl der Pipes) mehrere
>> MOV-CMP-MOV-Operationen ausgeführt werden.
>
> Klingt jetzt erstmal nach serialisieren. Z.B. könne ich eine ObjektId
> (Toid) dazu verwenden, eine critical section, oder sowas auszuwählen,
> damit die Kerne sich seltener gegenseitig aufhalten.


Das macht das Protokoll automatisch - der Programmierer hat auf
die Kommunikation der Kerne untereinander wenig Einfluss.


> Angenehm wäre mir allerdings, wenn sich dieses unerwartete LOCK CMPXCHG
> Verhalten (so es nicht an irgendwelchen sonstigen Fehlern lag)
> aufklären täte. Ich könnte ja problemlos damit leben, da eben
> falsche Erwartungen gehabt zu haben, nur wo, das wäre dann schon
> interessant. Hat mich immerhin schon einige Stunden gekostet, mir
> dieses compare-and-swap basierte System auszudenken.


http://wiki.osdev.org/Spinlock

Bernhard Schornak

unread,
Dec 6, 2014, 6:13:58 AM12/6/14
to
Peter J. Holzer schrieb:


> On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
>> Wer verwendet schon freiwillig CMPXCHG?
>
> Leute, die Locking-Primitives schreiben?


Das hat zwar mit Assembler rein gar nix zu tun, aber trotzdem:

http://locklessinc.com/articles/locks/


>> In derselben Zeit können parallel (abhängig von der Zahl der Pipes)
>> mehrere MOV-CMP-MOV-Operationen ausgeführt werden.
>
> Damit bekommst Du ein race-condition-freies Locking-Primitive hin?


Wahrscheinlich nicht. Wer viel will, muss viel dafür tun (oder
an der Börse zocken) - ein paar zusätzliche Befehle braucht es
sicher, um das zu realisieren.


> Ich will nicht ausschließen, dass das theoretisch möglich ist, aber ich
> glaube doch, dass sich die Intel-Leute was dabei gedacht haben, als sie
> (mit dem 486er?) CMPXCHG eingeführt haben.


http://en.wikipedia.org/wiki/Compare-and-swap

Seit wann -denken- iNTEL-Mitarbeiter denn? ;)

Jan Bruns

unread,
Dec 6, 2014, 8:22:40 PM12/6/14
to

Peter J. Holzer:
> Jan Bruns:

>> Anschinend müssen eher die Interlocked* Operationen single-core sein.
>> Warum wohl?

> Ich habe eher den Verdacht, dass Du irgendwo im waitchain-Handling einen
> Fehler hast. Den Code verstehe ich nämlich nicht, soweit Du ihn gezeigt
> hast (ein paar Kommentare im Code würden wirklich nicht schaden), und
> den Inhalt der Funktionen hast Du nicht gezeigt.

Danke. Sowas hatte ich gehofft hier zu lesen. Im offenbar ziemlich
gleiczeitig versandtem "Auflösungbeitrag" hat sich ja inzwischen schon
herausgestellt, daß Du mit deiner Vermutung recht hattest.

> Dadurch, dass Du lockObj auf eine CPU zwingst, läuft auch das ganze
> waitchain-Handling nur mehr auf einer CPU und damit seriell.

> Das cmpxchng auf Deinem System (CPU+Memory-Controller) buggy ist, kann
> man zwar nicht 100% ausschließen, ist aber doch ziemlich
> unterschiedlich. Das würde nämlich jedes Betriebssystem und jede
> Multithreading-Library (und jedes Programm, das sie verwendet),
> ebenfalls betreffen.

Das ist ja der Fall: In den letzten Jahren hatten derart viele
Anwendungen daerart häufig irgendwelche von den Anwendungsentwicklern
so sicherlich nicht geplante Verhaltensweisen, daß sich wahrlich nicht
der Eindruck einstellt, es würde alles bestens zusammenspielen.

Weiter wäre unter der Annahme, daß derart offensichtliche
Kohärenzfehler bei "lock cmpxchg" bei CPUs mit signifikantem
Verbreitungsgrad vorhanden sind, diese Information sicherlich
auch zu den Entwicklern von multithreading libraries durchgedrungen
(das habe ich ja ich so schnell nicht überblick, wann dort dort was
für workarounds wurde). Aus der Ecke hatte ich eher so die vage
Hintergrundinformaion, daß bei nackten lowlevel Synchronisations-
Elementen allgemein mit Unzuverlässigem Verhalten zu rechnen ist
(da überzeugt dann auch eine breite Masse an Meldungen erfolgreicher
Anwendungen nicht wirklich).

Ich dachte mir ferner, zu Zeiten, als dieses Lock-Präfix erdacht wurde,
hatte man auch allgemein andere Sorgen, als die Multibusmaster Kohärenz
speziell von adressierten Datenelementen. Allenfalls wird man an, so
dachte ich, an halbfertige, mehrzyklige Schreiboperationen gedacht
haben. Das stimmt aber so nicht, im 8086 Benutzerhandbuch wird bereits
die Verwendung des LOCK-Preäfixes in Verbindung mit dem XCHG-Befehl
zur Implementation von Semaphores/Locks beschrieben.

Gruss

Jan Bruns





Peter J. Holzer

unread,
Dec 7, 2014, 8:45:05 PM12/7/14
to
On 2014-12-06 11:14, Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>> On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
>>> Wer verwendet schon freiwillig CMPXCHG?
>>
>> Leute, die Locking-Primitives schreiben?
>
>
> Das hat zwar mit Assembler rein gar nix zu tun,

Letztendlich muss es in Assembler implemetiert werden. Entweder in einer
Library oder durch den Compiler.

> aber trotzdem:
>
> http://locklessinc.com/articles/locks/

| Unfortunately, we will require a few others that are not,
[ provided by gcc ]
| and so must be implemented in assembly

Da steht's ja.

XCHG macht übrigens ein implizites LOCK, dürfte also nicht wesentlich
billiger sein als ein LOCK CMPXCHG.


>>> In derselben Zeit können parallel (abhängig von der Zahl der Pipes)
>>> mehrere MOV-CMP-MOV-Operationen ausgeführt werden.
>>
>> Damit bekommst Du ein race-condition-freies Locking-Primitive hin?
>
>
> Wahrscheinlich nicht.

Eben.

> Wer viel will, muss viel dafür tun (oder an der Börse zocken) - ein
> paar zusätzliche Befehle braucht es sicher, um das zu realisieren.

Mit "ein paar zusätzlichen Befehlen" werden Race-Conditions meistens
nicht besser.

>> Ich will nicht ausschließen, dass das theoretisch möglich ist, aber ich
>> glaube doch, dass sich die Intel-Leute was dabei gedacht haben, als sie
>> (mit dem 486er?) CMPXCHG eingeführt haben.
>
>
> http://en.wikipedia.org/wiki/Compare-and-swap

| In the x86 (since 80486) and Itanium architectures this is implemented
| as the compare and exchange (CMPXCHG) instruction, though here the
| LOCK prefix should be there to make it really atomic.

Wo ist da der Widerspruch?

Jan Bruns

unread,
Dec 8, 2014, 2:29:20 AM12/8/14
to
Bernhard Schornak:

> Was sich auf
>
> mov %edx, %eax
> lock cmpxchg %esi, (%rdi)
> ret
>
> reduzieren liesse. Der Rest ist redundant, da die einzige hier
> ausgeführte Sequenz keinen Stapelrahmen (stackframe) benötigt. Die
> verwendeten Register sind laut "64 Bit Calling Convention" der Linux-API
> als "volatile" definiert, sie müssen somit nicht gesichert und wieder
> hergestellt werden. Bei Windows-64 müsste man RDI und RSI sichern. Es
> geht auch ganz ohne Stapelrahmen:

Ich kann Dir grad gar nicht genau sagen, was für eine calling
convention die Funktion verwendet. Es handelt sich ja wie gesagt
um eine quasi Compiler-eigene Funktion aus der "System-Unit", deren
Quelltext auch aus so vielen Dateien zusammengewürfelt ist, daß man
deren Aufbau nur sehr Mühsam nachvollziehen kann. Jedenfalls hat der
Compiler die Funktion ganz offenbar nicht direkt geinlined (also ganz
ohne call/ret), was er von mir aus auch gerne hätte machen können.

Scheint aber ja "zufällig" nach einem SystemV64-ABI kompatiblen
Aufrauf auszusehen.

Stimmt zwar, daß das unnötige Stackframe irgendwie ranzig aussieht,
aber vielleicht hat das ja Gründe. Denkbar wäre z.B., daß das wegen
irgendwelcher Stack-Unwinding Geschichten angelegt wird. Wenn z.B.
der das cmpxchg zu einer Speicherzugriffsverletzung führt, erhalte
ich ja nicht nur einfach eine Exception, sondern auch noch daren
letzte Gegenmassnahme, die sich in diesem Fall so ausgestaltet,
daß mir ein ungewindeter Call-Trace angezeigt wird, vielleicht
sogar mit den Namen der Quelltextdateien und Zeilennummern.

Gruss

Jan Bruns


Jan Bruns

unread,
Dec 8, 2014, 3:14:10 AM12/8/14
to

Bernhard Schornak:


>> Angenehm wäre mir allerdings, wenn sich dieses unerwartete LOCK CMPXCHG
>> Verhalten (so es nicht an irgendwelchen sonstigen Fehlern lag)
>> aufklären täte. Ich könnte ja problemlos damit leben, da eben falsche
>> Erwartungen gehabt zu haben, nur wo, das wäre dann schon interessant.
>> Hat mich immerhin schon einige Stunden gekostet, mir dieses
>> compare-and-swap basierte System auszudenken.
>
>
> http://wiki.osdev.org/Spinlock

Die Idee hinter dem ganzen ist aber doch gerade, Spinlocks im
Userland zu vermdeiden: Fordert ein AP Zugriff auf ein besetztes
Objekt, dann ist völlig unklar, wie lange es noch dauern wird, bis
das Objekt wieder frei ist, und es bedarf der Hilfe des Betriebs-
systems, den Rest der gerade laufenden Time-slice idealerweise auf
den Thread zu verlagern, der das Objekt gerade belegt, oder
wenigstens sonst irgendwie was sinnvolles zu machen.

Ich habe in meinem Code (im nicht gezeigten Teil) ist eine Stelle,
in der anfangs noch ein Spinlock war. Das war an der Stelle, wo
uunlockObj() das Objekt an einen anderen AP weitergibt, dazu aber
erstmal die waitchain sperren muss. Die kann durch einen sich gerade
einklinkenden AP, der das Objekt auch noch haben will, für einen
normalerweise ganz kurzen Moment Zugriffsgeschützt sein. Dieser
kurze Moment kann aber effektiv sehr lang werden, wenn man im
Vergleich zur Anzahl an CPUs viele aktive Threads hat, und der
sich einklingenden Thread im falschen Moment unterbrochen wurde.
Daher mache ich selbst dort nur ganz wenige nackte spinlock loops,
dann einige Durchläufe mit ThreadSwitch()-Versuch, und letzlich
weiter mit (unzuverlässigem) Signalwarten.

Die hier gezeigten loops laufen jedenfalls nur ganz selten mal
eine zweite Runde, obwohl in lockObj() eigentlich auch sowas
passieren kann, wie im vorigen Absatz beschrieben.

Gruss

Jan Bruns

Bernhard Schornak

unread,
Dec 8, 2014, 10:56:15 AM12/8/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>
>> Was sich auf
>>
>> mov %edx, %eax
>> lock cmpxchg %esi, (%rdi)
>> ret
>>
>> reduzieren liesse. Der Rest ist redundant, da die einzige hier
>> ausgeführte Sequenz keinen Stapelrahmen (stackframe) benötigt. Die
>> verwendeten Register sind laut "64 Bit Calling Convention" der Linux-API
>> als "volatile" definiert, sie müssen somit nicht gesichert und wieder
>> hergestellt werden. Bei Windows-64 müsste man RDI und RSI sichern. Es
>> geht auch ganz ohne Stapelrahmen:
>
> Ich kann Dir grad gar nicht genau sagen, was für eine calling
> convention die Funktion verwendet.


Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
handeln.

http://agner.org/optimize/calling_conventions.pdf


> Es handelt sich ja wie gesagt
> um eine quasi Compiler-eigene Funktion aus der "System-Unit", deren
> Quelltext auch aus so vielen Dateien zusammengewürfelt ist, daß man
> deren Aufbau nur sehr Mühsam nachvollziehen kann. Jedenfalls hat der
> Compiler die Funktion ganz offenbar nicht direkt geinlined (also ganz
> ohne call/ret), was er von mir aus auch gerne hätte machen können.
>
> Scheint aber ja "zufällig" nach einem SystemV64-ABI kompatiblen
> Aufrauf auszusehen.
>
> Stimmt zwar, daß das unnötige Stackframe irgendwie ranzig aussieht,
> aber vielleicht hat das ja Gründe. Denkbar wäre z.B., daß das wegen
> irgendwelcher Stack-Unwinding Geschichten angelegt wird. Wenn z.B.
> der das cmpxchg zu einer Speicherzugriffsverletzung führt, erhalte
> ich ja nicht nur einfach eine Exception, sondern auch noch daren
> letzte Gegenmassnahme, die sich in diesem Fall so ausgestaltet,
> daß mir ein ungewindeter Call-Trace angezeigt wird, vielleicht
> sogar mit den Namen der Quelltextdateien und Zeilennummern.


Der einzige Grund, redundanten Code zu generieren, ist der, dass
diejenigen, die derartige Konstrukte produzieren, keinen blassen
Schimmer von Assemblerprogrammierung haben. Bei Exceptions würde
die Inhalte aller Register vor der Abarbeitung gesichert und zu-
dem in Logfiles gespeichert, um dem Anwendungsprogrammierern die
Fehlersuche zu ermöglichen - sicher kein Argument für den Aufbau
überflüssiger Stapelrahmen...

Bernhard Schornak

unread,
Dec 8, 2014, 10:58:04 AM12/8/14
to
Jan Bruns schrieb:
Wie Du aus dem vorhergehenden Reply entnomen haben solltest, kann
ich als Assemblerprogrammierer (ich verwende keine Hochsprachen!)
nur dann helfen, wenn ich Assemblercode (AT&T oder iNTEL) vor mir
habe. Erst dann kann ich nachvollziehen, was beim Ausführen einer
Funktion auf einem bestimmten Kern passiert und wie sich das dann
auf andere Kerne/Prozessoren auswirken könnte.

Auf Maschinenebene gibt es nur abzuarbeitende Befehle und Daten -
Konstrukte wie Objekte und Threads existieren -nur- in den Köpfen
der Hochsprachenprogrammierer. Während die Maschine nur eine sehr
komplexe Abfolge privilegierter Befehle abarbeitetet, "sieht" der
Hochsprachenprogrammierer hier Threads und Objekte, die kaum mehr
als abstrakte, von der aktuell verwendeten -Hardware- vollständig
losgelöste Gedankenspiele sind.

Es ist müssig, in einer Assembler-NG über hochsprachenspezifische
Probleme zu klagen, ohne eine Zeile Assemblercode vorzulegen, die
das Fehlverhalten der Hochsprache aufzeigen könnte. Der gepostete
Ausschnitt ist sicher nicht die Ursache des Fehlverhaltens - dazu
müsste man schon ein wenig mehr davon sehen, was der Compiler aus
Deinem Code generiert hat. Mit GCCs "-s"-Option lässt sich jeder-
zeit die an AS übergebene Assemblerdatei ausgeben. Vielleicht ist
dann jemand in der Lage, Dir -hier- weiterzuhelfen.

Bernhard Schornak

unread,
Dec 8, 2014, 10:59:15 AM12/8/14
to
Peter J. Holzer schrieb:


> On 2014-12-06 11:14, Bernhard Schornak <scho...@web.de> wrote:
>> Peter J. Holzer schrieb:
>>> On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
>>>> Wer verwendet schon freiwillig CMPXCHG?
>>>
>>> Leute, die Locking-Primitives schreiben?
>>
>>
>> Das hat zwar mit Assembler rein gar nix zu tun,
>
> Letztendlich muss es in Assembler implemetiert werden. Entweder in einer
> Library oder durch den Compiler.


Ja - mit der Kompetenz von HLL-Compilerbauern... ;)


> XCHG macht übrigens ein implizites LOCK, dürfte also nicht wesentlich
> billiger sein als ein LOCK CMPXCHG.


AMD : 5 Takte FP-Double statt 6/7 Takte Complex
iNTEL: 1.5 (???) statt 5 Takte

Wobei iNTEL's Angaben (mit viertel, drittel und halben Takten)
mit äusserster Vorsicht zu geniessen sind.


>> Wer viel will, muss viel dafür tun (oder an der Börse zocken) - ein
>> paar zusätzliche Befehle braucht es sicher, um das zu realisieren.
>
> Mit "ein paar zusätzlichen Befehlen" werden Race-Conditions meistens
> nicht besser.


Je mehr Code, desto grösser die Verzögerung. Reicht meist aus,
die Schreibarbeit eines anderen Kerns zu "verstecken". Es gibt
aber auch die Möglichkeit, Aufgaben so aufzuteilen, dass jeder
Thread sich mit einem Teil des Speichers beschäftigt, den kein
anderer Thread in absehbarer Zukunft antasten wird. Das dürfte
die Abarbeitung um den Faktor zehn oder mehr beschleunigen.


>>> Ich will nicht ausschließen, dass das theoretisch möglich ist, aber ich
>>> glaube doch, dass sich die Intel-Leute was dabei gedacht haben, als sie
>>> (mit dem 486er?) CMPXCHG eingeführt haben.
>>
>>
>> http://en.wikipedia.org/wiki/Compare-and-swap
>
> | In the x86 (since 80486) and Itanium architectures this is implemented
> | as the compare and exchange (CMPXCHG) instruction, though here the
> | LOCK prefix should be there to make it really atomic.
>
> Wo ist da der Widerspruch?


Welcher Widerspruch in Relation zu was? Wer daran glaubt, dass
eine Ausführungseinheit (Execution Pipe) in -einem- Taktzyklus
-bis zu vier- Befehle ausgeführt werden können (das heisst: Es
werden 4 Ergebnisse pro Takt geliefert!), der hat Physik durch
Religion ersetzt. Religion fordert Glauben statt Denken - ergo
können die iNTELianer (wie alle guten Bewohner der USA!) nicht
denken... ;)

Jan Bruns

unread,
Dec 8, 2014, 9:49:45 PM12/8/14
to

Bernhard Schornak:

>>> http://en.wikipedia.org/wiki/Compare-and-swap
>> Wo ist da der Widerspruch?
> Welcher Widerspruch in Relation zu was?

Du hattest gewitzelt, daß man sich bei intel selbst
möglicherweise nur wenig Gedanken über die Vorteile von CAS
gemacht haben könnte, da "die Wissenschaft" das zuvor schon
theoretisiert hatte.

> Wer daran glaubt, dass eine
> Ausführungseinheit (Execution Pipe) in -einem- Taktzyklus -bis zu vier-
> Befehle ausgeführt werden können (das heisst: Es werden 4 Ergebnisse pro
> Takt geliefert!), der hat Physik durch Religion ersetzt. Religion
> fordert Glauben statt Denken - ergo können die iNTELianer (wie alle
> guten Bewohner der USA!) nicht denken... ;)


Das ist aber so, solange die Befehle unabhängig
voneinander sind.

Ein ganz zentrales Bauteil, das man dazu braucht,
und das, glaube ich, sehr schön geeignet ist,
wenigstens eine grobe Vorstellung von den Abläufen
zu entwickeln, ist das Mehrport-RAM.

Nehmen wir z.B. an, wir wollten für die Register
eines IA-32 Systems so ein Bauteil haben. Es mag
etwas übertrieben erscheinen, aber fordern wir
doch einfach, daß 4 x86-Befehle ohne Einschränkungen
(abgesehen von der Abhängigkeit der Befehle von
vorigen) gleichzeitig ausgeführt werden können sollen.

Dazu bräuchten wir so im Prinzip ein 12-Port RAM, mit
8 Leseports (4 x86 Befehle könen je 2 Quelloperanden
haben), sowie 4 unabhägige Schreibports, um die
Ergebnisse des vorigen, oder irgendwie noch schöner:
des gleichen Taktes loszuwerden.

Ein solches Bauteil kann man durchaus herstellen:

Man nimmt z.B. für jedes zu implementierende
Registerbit ein einzelnes FlipFlop. Daran kann man
beliebig viele Leseports anschliessen, indem man
die Leseports als MUX-Schaltungen (d.h. one of n)
ausführt, in diesem Fall also, da IA32 nur 8 Register
hat, eine MUX8-Schaltung pro Bit eines Leseports.
Für die 4 Schreibports kann man vor den Dateineingang
eines jeden FlipFlops eine MUX4-Schaltung zur Auswahl
des für dieses Bit zu verwendenden Schreibports
schalten. Weiters das Write-Enable des FlipFlops
beschalten.

Somit haben wir ein letzlich eigentlich ganz
einfaches Teil, an das wir 4 ALUs anschliessen
können, die alle ganz wunderbar gleichzeitig
im selben Takt rechnen können, und unabhängig
voneinander all ihre Ergebnisse wieder zurück
ins Registerfile schreiben können.

Das alles dann so zu koordinieren daß letzlich
nur ein einzelner Befehlsstrom abgearbeitet wird,
ist natürlich kompliziert, aber eben nur in dem
Sinne, daß unsäglich viele Details zu beachten
sind.

Gruss

Jan Bruns

Jan Bruns

unread,
Dec 8, 2014, 10:18:14 PM12/8/14
to

Bernhard Schornak:
> Jan Bruns schrieb:

>> Ich kann Dir grad gar nicht genau sagen, was für eine calling
>> convention die Funktion verwendet.

> Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
> handeln.

cmpxchg %esi, (%rdi)

verändert doch RDI und RSI gar nicht, also bräuchte auch dann
nichts gesichert werden, wenn der callee die zu erhalten hätte.

>> Stimmt zwar, daß das unnötige Stackframe irgendwie ranzig aussieht,
>> aber vielleicht hat das ja Gründe. Denkbar wäre z.B., daß das wegen
>> irgendwelcher Stack-Unwinding Geschichten angelegt wird. Wenn z.B. der
>> das cmpxchg zu einer Speicherzugriffsverletzung führt, erhalte ich ja
>> nicht nur einfach eine Exception, sondern auch noch daren letzte
>> Gegenmassnahme, die sich in diesem Fall so ausgestaltet, daß mir ein
>> ungewindeter Call-Trace angezeigt wird, vielleicht sogar mit den Namen
>> der Quelltextdateien und Zeilennummern.

> Der einzige Grund, redundanten Code zu generieren, ist der, dass
> diejenigen, die derartige Konstrukte produzieren, keinen blassen
> Schimmer von Assemblerprogrammierung haben. Bei Exceptions würde die
> Inhalte aller Register vor der Abarbeitung gesichert und zu- dem in
> Logfiles gespeichert, um dem Anwendungsprogrammierern die Fehlersuche zu
> ermöglichen - sicher kein Argument für den Aufbau überflüssiger
> Stapelrahmen...

Hast Du schonmal versucht, den call-stack zurückzuverfolgen?
Ist das dabei wohl hilfreich, wenn jeder call seine frames beliebig
gestaltet? Dann musst man zum unwinden eine Tabelle haben, in der
für jeden call-codepunkt, und zudem für jeden Ort, an dem eine
Exception auftreten kann, die für den Position verwendete Stackverwendung
verzeichnet ist. Kann man auch machen, aber b da nicht einfach zu faul
zu ist, ist natürlich eine andere Frage. Dann bleibt aber nur noch die
Wahl, entweder auf solche hilfreichen anwinds zu verzichten, oder
eben zuweilen überflüssige Stackframes anzulegen.

Überhaupt nervt das übrigens ein wenig, so dieses andauernde
thematisieren der Kompetenz anderer Leute. Da könntest Du mal
dran arbeiten, das zu minimieren.


Gruss

Jan Bruns






Bernhard Schornak

unread,
Dec 9, 2014, 9:53:54 AM12/9/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>
>>>> http://en.wikipedia.org/wiki/Compare-and-swap
>>> Wo ist da der Widerspruch?
>> Welcher Widerspruch in Relation zu was?
>
> Du hattest gewitzelt, daß man sich bei intel selbst
> möglicherweise nur wenig Gedanken über die Vorteile von CAS
> gemacht haben könnte, da "die Wissenschaft" das zuvor schon
> theoretisiert hatte.


Das ist mir neu. Wo genau soll das gewesen sein? Ich traue dem
Monopolisten iNTEL zwar zu, mit unlauteren Mitteln weit unter-
halb der Gürtellinie auf dem Markt zu agieren, man sollte aber
fair bleiben, und iNTEL zugestehen, viele Technologien selbst,
respektive vorhandene Technologien weiterentwickelt zu haben.

"Die Wissenschaft" ist ein schwammiger Begriff, der auf keinen
Fall aus meiner Feder stammt.
Das hört sich erst einmal so schlüssig an, dass ich mich etwas
gründlicher damit beschäftigen werde. Dagegen spricht, dass es
seit etlichen Prozessorgenerationen nicht mehr die 8 (oder 16)
bekannten Register rAX, rBX, et cetera gibt, sondern ein paar-
hundert Scratch-Register, denen je nach Bedarf einer der Namen
rAX, rBX, et cetera zugewiesen wird. Es wäre durchaus möglich,
jedes dieser Register mit multiplen I/O-Ports auszurüsten, die
gelegentlich sicher einmal genutzt würden. Die dafür benötigte
Verwaltung dürfte andererseits so komplex werden, dass sie auf
keinen Chip mehr passt. Zudem ergäbe sich das Problem, dass es
bei vier in einem einzigen Takt innerhalb einer einzelnen Pipe
abgearbeiteten Befehlen auch vier Datenbusse die 256 I/O-Ports
in einem Takt mit Daten versorgen müssten, was die (maximal 3)
von iNTEL bereit gestellten 64 Bit breiten Datenpfade zwischen
Prozessor und Hauptspeicher (maximal 192 Bit) nicht zulassen.

Abgesehen davon müsste auch der Befehlsdecoder nicht nur eine,
sondern vier Einheiten pro Pipe mit Befehlen versorgen. Insge-
samt bleiben da mehr offene Fragen über, als zuvor beantwortet
wurden. Zudem erklärt das leider noch nicht, wie ein Befehl in
0,33 oder 0,66 Taktzyklen abgearbeitet werden könnte, drei ist
schliesslich keine Zweierpotenz.

(Abgesehen davon: Wie misst man Zeiten, die nur Bruchteile des
Taktes betragen? Bei einer Frequenz von 4 GHz beträgt ein Takt
250 ps. Das Signal legt in dieser Zeit eine Strecke von 7,5 cm
zurück, bei einem Viertel demnach 1,875 cm - eine verlässliche
Messung liesse sich also nur durchführen, wenn der Proband und
das Messgerät nicht mehr als einen Zentimeter voneinander ent-
fernt wären...)

Bernhard Schornak

unread,
Dec 9, 2014, 9:54:44 AM12/9/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>> Jan Bruns schrieb:
>
>>> Ich kann Dir grad gar nicht genau sagen, was für eine calling
>>> convention die Funktion verwendet.
>
>> Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
>> handeln.
>
> cmpxchg %esi, (%rdi)
>
> verändert doch RDI und RSI gar nicht, also bräuchte auch dann
> nichts gesichert werden, wenn der callee die zu erhalten hätte.


Das weiss der Compiler, der diese Sequenz erzeugt hatte, ganz
sicher nicht. Er weiss nur, dass er RSI und RDI nicht sichern
muss (selbst dann, wenn er einen Stapelrahmen aufgebaut hat),
da das im "Application Binary Interface" so definiert ist. Da
das Win-64-ABI die Sicherung dieser Register vorschreibt (und
minGW das auch so compiliert), kann es sich nur um ein Linux-
Konstrukt handeln.

Der verschwenderische Umgang mit Ressourcen war unter Anderem
der Grund, weshalb ich (überzeugter Open-Source-Programierer)
2009 von OS/2 nicht auf Linux, sondern auf 64 Bit Windows um-
gestiegen bin. Wenn nur sechs von 32 Registern (18,75%!) nach
einem Aufruf den gleichen Wert wie davor haben, bedeutet das,
dass ich 26 von 32 Registern (81,25%!) vor dem Aufruf sichern
und anschliessend wieder vom Stapel laden muss. Bei Windows64
wurde nur die Hälfte, also 13 von 32 Registern (40,625%), als
"volatile" definiert, was gerade noch im Grenzbereich des Er-
träglichen liegt.

Wer Wert auf unveränderte Register nach einem Funktionsaufruf
legt, muss seine API-Aufrufe in so genannte "Wrapper" packen,
deren einziger Sinn es ist, die vom Betriebssystem zerstörten
Registerinhalte vor jedem Aufruf zu sichern und danach wieder
in die überschriebenen Register zu laden:

https://code.google.com/p/st-open/source/browse/LIB/SOURCES/core/cap.S


>>> Stimmt zwar, daß das unnötige Stackframe irgendwie ranzig aussieht,
>>> aber vielleicht hat das ja Gründe. Denkbar wäre z.B., daß das wegen
>>> irgendwelcher Stack-Unwinding Geschichten angelegt wird. Wenn z.B. der
>>> das cmpxchg zu einer Speicherzugriffsverletzung führt, erhalte ich ja
>>> nicht nur einfach eine Exception, sondern auch noch daren letzte
>>> Gegenmassnahme, die sich in diesem Fall so ausgestaltet, daß mir ein
>>> ungewindeter Call-Trace angezeigt wird, vielleicht sogar mit den Namen
>>> der Quelltextdateien und Zeilennummern.
>
>> Der einzige Grund, redundanten Code zu generieren, ist der, dass
>> diejenigen, die derartige Konstrukte produzieren, keinen blassen
>> Schimmer von Assemblerprogrammierung haben. Bei Exceptions würde die
>> Inhalte aller Register vor der Abarbeitung gesichert und zu- dem in
>> Logfiles gespeichert, um dem Anwendungsprogrammierern die Fehlersuche zu
>> ermöglichen - sicher kein Argument für den Aufbau überflüssiger
>> Stapelrahmen...
>
> Hast Du schonmal versucht, den call-stack zurückzuverfolgen?


Was ist ein "call-stack"? Assembler kennt ein Stacksegment SS
und den Stackpointer rSP. Da das Stacksegment SS in der Regel
vom Betriebssystem gesetzt wird und im Protected Mode von den
Anwendungsprogrammierern und Compilern nicht verändert werden
kann, ist nur der Stapelzeiger rSP änderbar.

HLL-Compiler "wissen", dass rSP bei jedem CALL auf dem Stapel
abgelegt wird und dann vier (32 Bit OS) oder acht (64 Bit OS)
von rSP abgezogen werden. "Stapelrahmen" können konventionell
über das rSP/rBP-Paar oder zeitgemäss mittels Abziehen des in
der Funktion benötigten Platzbedarfs von rSP und Addition der
selben Summe beim Verlassen der Funktion aufgebaut / zerstört
werden.

http://tinyurl.com/oxwepcr


> Ist das dabei wohl hilfreich, wenn jeder call seine frames beliebig
> gestaltet? Dann musst man zum unwinden eine Tabelle haben, in der
> für jeden call-codepunkt, und zudem für jeden Ort, an dem eine
> Exception auftreten kann, die für den Position verwendete Stackverwendung
> verzeichnet ist. Kann man auch machen, aber b da nicht einfach zu faul
> zu ist, ist natürlich eine andere Frage. Dann bleibt aber nur noch die
> Wahl, entweder auf solche hilfreichen anwinds zu verzichten, oder
> eben zuweilen überflüssige Stackframes anzulegen.


Könntest Du das bitte auf Deutsch wiederholen? Ich kann jetzt
wild raten, dass das "b" ein "ob" sein sollte, davon wird der
Satz aber nicht unbedingt verständlicher.


> Überhaupt nervt das übrigens ein wenig, so dieses andauernde
> thematisieren der Kompetenz anderer Leute. Da könntest Du mal
> dran arbeiten, das zu minimieren.


Ich arbeite seit mehr als 35 Jahren mit Assemblern (68k, x86,
x86-64) - es dürfte schwer sein, mir etwas unterzujubeln, das
nicht koscher ist. Wenn ich einen Fehler sehe, weise ich auch
darauf hin, das ist letztendlich der Sinn einer Newsgroup für
Programmierer. Wenn ich Fehler aufzeige, erlaube ich mir, auf
offensichtliche Dinge hinzuweisen. Wenn "Compiler-Bauer" ihre
Compiler vorsätzlich redundanten Code erzeugen lassen, leiden
dadurch nicht nur die Benutzer, sondern auch die Ressourcen -
Milliarden Prozessoren sind unnötigerweise länger beschäftigt
und schalten zwangsläufig weit weniger oft in energiesparende
Betriebsmodi. Es geht somit um ein globales Problem, nicht um
Befindlichkeiten einiger Individuen.

Leider halten wir es heutezutage für unnötig, uns über solche
simplen Zusammenhänge Gedanken zu machen, vergiessen aber ki-
loweise Krokodilstränen über eine globale Erwärmung, die erst
durch unser aktives (Produzenten) oder passives (Konsumenten)
Tun entstand und gedankenlos am Leben erhalten wird.

Jan Bruns

unread,
Dec 10, 2014, 1:11:36 AM12/10/14
to

Bernhard Schornak:
> Jan Bruns schrieb:

>> Du hattest gewitzelt, daß man sich bei intel selbst möglicherweise nur
>> wenig Gedanken über die Vorteile von CAS gemacht haben könnte, da "die
>> Wissenschaft" das zuvor schon theoretisiert hatte.

> Das ist mir neu. Wo genau soll das gewesen sein?

Wie sonst soll man das hier

| > Ich will nicht ausschließen, dass das theoretisch möglich ist, aber ich
| > glaube doch, dass sich die Intel-Leute was dabei gedacht haben, als sie
| > (mit dem 486er?) CMPXCHG eingeführt haben.
|
| http://en.wikipedia.org/wiki/Compare-and-swap
|
| Seit wann -denken- iNTEL-Mitarbeiter denn? ;)

denn deuten? Das hast Du geschrieben in
Date: Sat, 06 Dec 2014 12:14:12 +0100
Message-ID: <m5uod3$9t0$3...@dont-email.me>


> Das hört sich erst einmal so schlüssig an, dass ich mich etwas
> gründlicher damit beschäftigen werde. Dagegen spricht, dass es seit
> etlichen Prozessorgenerationen nicht mehr die 8 (oder 16) bekannten
> Register rAX, rBX, et cetera gibt, sondern ein paar- hundert
> Scratch-Register, denen je nach Bedarf einer der Namen rAX, rBX, et
> cetera zugewiesen wird.

Ja, aber das spricht doch nicht dagegen. Zumindest
nicht so direkt.

Dann muss eben für jedes Bit der Leseports nicht
mehr ein MUX8, sondern ein entsprechend grösseres
MUX her. Bestimmt kann man die dennoch mit einer
effektiven Schaltungstiefe von 2 levels implementieren.

So ein Register-renaming kann sicherlich dabei
helfen, für eine bessere Auslastung zu sorgen.

So spontan fällt mir folgende Situation als
Beispiel ein (natürlich nicht auf irgendeine
bestimmte CPU bezogen):

l1: nop
l2: nop
l3: nop
l4: mov ebx,dword ptr[]

l5: add ebx,eax
l6: inc eax
l7: nop
l8: nop

l9: add ecx,eax
la: nop
lb: nop
lc: nop

Wenn die ersten 4 Befehle gleichzeitig ausgeführt
werden, stellt sich ja wohl heraus, daß einer
davon ein Speicherzugriff ist, der sicherlich
nicht im nächsten Takt schon fertig sein wird.

Somit kann der Befehl bei @l5 im zweiten Takt
noch nicht ausgeführt werden, und muss wenigstens
noch einen Takt warten.

Ohne Register-renaming gälte das dann aber auch
für den Befehl bei @l6, weil der einen Quelloperanden
von @l5 verändert. Somit müsste möglichereise auch @l9
auf einen 4. Zyklus verschoben werden, weil der ja von
@l6 abhängt (ok, ein einfaches inc mag so ein komplexes
Verarbeitungssystem u.U. vielleicht gerade noch so
als Zusatzeigenschaft der Register verwalten können,
wenn dann wieder eine Addition folgt).

Mit register-renaming könnte dagegen sowas zu
machen sein:


l1: nop
l2: nop
l3: nop
l4: mov ebx,dword ptr[] // erster Zyklus

l6: inc eax
l7: nop
l8: nop
l4: mov ebx,dword ptr[] // zweiter Zyklus

l5: add ebx,old_eax
l9: add ecx,eax
la: nop
lb: nop



> Abgesehen davon müsste auch der Befehlsdecoder nicht nur eine, sondern
> vier Einheiten pro Pipe mit Befehlen versorgen.

Äh, ja, natürlich.
Z.B. mit einer 4-stufigen pipeline:
Nehmen wir an, man hat ein Bauteil, das in einem
Takt einen Befehl aus einem Datenstrom herausfischen
kann, und einer nachfolgenden Stufe noch mitteilen
kann, wo der nächste Befehl anfangen müsste.
Dann liefern 4 solche Bauteile hintereinandergeschaltet,
wenn der next_pointer der letzten Stufe von
der ersten Stufe aufgegriffen wird, pro Takt 4 Befehle.

Gruss

Jan Bruns





Jan Bruns

unread,
Dec 10, 2014, 1:46:54 AM12/10/14
to

Jan Bruns:

>> Abgesehen davon müsste auch der Befehlsdecoder nicht nur eine, sondern
>> vier Einheiten pro Pipe mit Befehlen versorgen.
>
> Äh, ja, natürlich.
> Z.B. mit einer 4-stufigen pipeline:
> Nehmen wir an, man hat ein Bauteil, das in einem Takt einen Befehl aus
> einem Datenstrom herausfischen kann, und einer nachfolgenden Stufe noch
> mitteilen kann, wo der nächste Befehl anfangen müsste. Dann liefern 4
> solche Bauteile hintereinandergeschaltet, wenn der next_pointer der
> letzten Stufe von der ersten Stufe aufgegriffen wird, pro Takt 4
> Befehle.

Halt, nee, so einfach geht's nicht ganz.
Mit n-stufiger Pipeline ist ja eigentlich gemeint,
daß n Bauteile gleichzeitig arbeiten, aber jeweils
immer um einen Takt verzögert.

So ginge es aber natürlich, wenn die Stufen alle im gleichen
Takt hintereinandergeschaltet wären. Das mag etwas knapp sein.



Gruss

Jan Bruns



Jan Bruns

unread,
Dec 10, 2014, 4:49:37 AM12/10/14
to

Jan Bruns:


> Halt, nee, so einfach geht's nicht ganz. Mit n-stufiger Pipeline ist ja
> eigentlich gemeint, daß n Bauteile gleichzeitig arbeiten, aber jeweils
> immer um einen Takt verzögert.
>
> So ginge es aber natürlich, wenn die Stufen alle im gleichen Takt
> hintereinandergeschaltet wären. Das mag etwas knapp sein.

Hm. Das ist hier zwar eigentlich keine Elektronikgruppe,
und ich Antworte mir erneut selbst, aber egal...

Was man da tatsächlich, real machen kann (ich kenne das Problem
von einer weit einfacheren, einzelinstruktions- CPU-Konstruktion...
das ist echt der Fluch, ständig irgendwo Cachelinegrenzen im
weg, über die Befehle sich aber erstecken können, und dann
gelichzeitig der Wunsch nach einer superkurzen Pipeline, damit
jumps nicht so teuer sind, und so):

Beim einladen einer Cacheline in einen "Befehlspuffer" in
diesem für jedes Byte zusätzlichen Platz vorsehen, für die
dekodierte Befehlslänge (mit der Annahme, ein Befehl starte
an diesem Byte), evtl. zus. die Entfernung zum übernächsten Befehl,
usw.

Also sowas

T_Instruktionpufferbyte = record
wert : byte;
nxt1,nxt2,nxt3,nxt4 : byte;
end


Direkt nach dem Einladen aus der Cacheline ist erst der Wert des Bytes
bekannt. Diese Datenstruktur ist dann aber in echt eine Schaltung,
also für jedes code-byte eine solche, die wieder über fette MUX auf den
Inhalt der anderen "bytes" zugreifen kann. Somit hat -abgesehen von
Detailfragen an Rändern von Cachelines, jedes code-"byte" die Möglichkeit,
die Länge des an seiner Position startenden Befehls auszurechnen:

Im Falle von x86 würde man vielleicht zunächst überall nxt1=0 setzen,
und das solange simultan inkrementieren lassen, bis die Befehlspräfixe
schonmal weggezählt sind. Dauert also 3 Zyklen, oder so, weiss grad
nicht, wieviele Präfixe auf x86 erlaubt bzw. häufig sind. Dann weiter
mit dem oder den Instruction Byte(s), und so fort bis endlich jedes
Code-Byte "weiss", wie lang sein Befehl ist bzw. wäre.

Sodann noch die Werte für nxt2,nxt3 und nxt4 austauschen, was wieder
3 Zyklen dauert.

Somit haben wir jetzt ganz gemächlich, sagen wir in 10-20 Zyklen
bei grossem Transistoraufwand (der heutzutage ja null interessiert)
einen Instruktions-Speicher erzeugt, der bereits vordekodierte Befehle
z.B. einer Cacheline enthält. Alternativ zu MUX könnte man die
code-bytes, bzw. nxt-Werte durchshiften.

Auf einem solchen Instruiktionspuffer funktioniert auch die anfangs
vorgeschlagene 4-stuufige Pipeline zur Befehlsdekodierung richtig,
weil nun die erste Stufe "weiss", wie sie 0-4 Befehle weiterspringen
kann.

So hat man unbedingte, kurze, relative Sprünge gleich höchst
effizient mit abgehakt.


Für besagte einzelinstruktions- CPU-Konstruktion war das aber alles
einfach viel zu "teuer" (und eine Beschränkung auf wenige
"Code-Bytes" macht das ganze ja auch nicht gerade attraktiv). Aber was
man sich in seiner Verzweiflung nicht alles noch gleich mit ausdenken
kann, ist schon interessant.


Gruss

Jan Bruns



Bernhard Schornak

unread,
Dec 10, 2014, 11:22:20 AM12/10/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>> Jan Bruns schrieb:
>
>>> Du hattest gewitzelt, daß man sich bei intel selbst möglicherweise nur
>>> wenig Gedanken über die Vorteile von CAS gemacht haben könnte, da "die
>>> Wissenschaft" das zuvor schon theoretisiert hatte.
>
>> Das ist mir neu. Wo genau soll das gewesen sein?
>
> Wie sonst soll man das hier
>
> | > Ich will nicht ausschließen, dass das theoretisch möglich ist, aber ich
> | > glaube doch, dass sich die Intel-Leute was dabei gedacht haben, als sie
> | > (mit dem 486er?) CMPXCHG eingeführt haben.
> |
> | http://en.wikipedia.org/wiki/Compare-and-swap
> |
> | Seit wann -denken- iNTEL-Mitarbeiter denn? ;)
>
> denn deuten? Das hast Du geschrieben in
> Date: Sat, 06 Dec 2014 12:14:12 +0100
> Message-ID: <m5uod3$9t0$3...@dont-email.me>


Ich weiss, was ich geschrieben hatte. Interessant ist, was
Du daraus "abgeleitet" hast... ;)

(Zwischen meiner persönlichen Meinung zu iNTEL und dem zi-
tierten Wiki-Artikel besteht kein kausaler Zusammenhang.)
Genau aus diesem Grund wurde eine "Out of Order Execution"
erfunden, die eingehende Befehle bereits beim Einlesen und
Dekodieren analysiert, und so in der Instruktions-Pipeline
ablegt, dass während ihrer Abarbeitung möglichst keine Ab-
hängigkeiten der von Dir geschilderten Form entstehen.

http://de.wikipedia.org/wiki/Out-of-order_execution

Abgesehen davon ist der Takt ein serieller Vorgang, der in
der Datenverarbeitung nur durch Parallelisierung (mehr Bit
pro Takt) einen höheren Datendurchsatz bringen kann.

<schnipp>

>> Abgesehen davon müsste auch der Befehlsdecoder nicht nur eine, sondern
>> vier Einheiten pro Pipe mit Befehlen versorgen.
>
> Äh, ja, natürlich.
> Z.B. mit einer 4-stufigen pipeline:
> Nehmen wir an, man hat ein Bauteil, das in einem
> Takt einen Befehl aus einem Datenstrom herausfischen
> kann, und einer nachfolgenden Stufe noch mitteilen
> kann, wo der nächste Befehl anfangen müsste.
> Dann liefern 4 solche Bauteile hintereinandergeschaltet,
> wenn der next_pointer der letzten Stufe von
> der ersten Stufe aufgegriffen wird, pro Takt 4 Befehle.


Seriell könnte das aber nur funktionieren, wenn solch eine
hypothetische Einheit mit dem vierfachen Takt (=> 16 GHz!)
betrieben wird. Der -bislang- schnellste Prozessor ist ein
mit Flüssiggas gekühlter Bulldozer bei 8,429 GHz:

http://tinyurl.com/6x4dqqx

Doppelt so viel ist mit der aktuellen Prozessortechnologie
rein physikalisch nicht realisierbar. Demnach könnte diese
Überlegung nur mit vier parallel arbeitenden Einheiten re-
alisiert werden, was aber sehr viel Silikon kostet. Ob man
dann noch einen L2-Cache auf das Die bringt, ist fraglich,
von einem L3-Cache bräuchten wir dann nicht einmal mehr zu
träumen...

Bernhard Schornak

unread,
Dec 10, 2014, 11:22:24 AM12/10/14
to
Jan Bruns schrieb:
Nicht hintereinander, sondern nebeneinander. Jede Stufe einer Pipe
kann pro Takt nur einen Datensatz bearbeiten. Bei zwei Datensätzen
müsste eine zweite Stufe vorhanden sein, um die zusätzlichen Daten
verarbeiten zu können. Theoretisch könnte man den Takt verdoppeln,
das scheitert aber schnell an physikalischen Problemen.

Bernhard Schornak

unread,
Dec 10, 2014, 11:22:33 AM12/10/14
to
Jan Bruns schrieb:
Das mag ein wenig weiter helfen:

http://www.chip-architect.com/news/2002_06_24_hammers_two_extra_pipelinestages.html
http://mail.humber.ca/~paul.michaud/Pipeline.htm

Auch die von AMD veröffentlichten Handbücher gehen relativ
detailliert auf den Aufbau der Prozessoren ein.

Peter J. Holzer

unread,
Dec 13, 2014, 5:53:20 AM12/13/14
to
On 2014-12-09 14:54, Bernhard Schornak <scho...@web.de> wrote:
> Jan Bruns schrieb:
>> Bernhard Schornak:
>>> Jan Bruns schrieb:
>>>> Ich kann Dir grad gar nicht genau sagen, was für eine calling
>>>> convention die Funktion verwendet.
>>
>>> Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
>>> handeln.

Das ist ein Fehlschluss.

>> cmpxchg %esi, (%rdi)
>>
>> verändert doch RDI und RSI gar nicht, also bräuchte auch dann
>> nichts gesichert werden, wenn der callee die zu erhalten hätte.
>
>
> Das weiss der Compiler, der diese Sequenz erzeugt hatte, ganz
> sicher nicht.

Wenn der Sequenz von einem Compiler erzeugt wurde (ich halte es für
nicht unwahrscheinlich, dass die handgeschrieben ist), dann weiß er das
ziemlich sicher sehr wohl. Wie soll er denn Code erzeugen, wenn er nicht
weiß, was eine Instruktion macht?

> Er weiss nur, dass er RSI und RDI nicht sichern
> muss (selbst dann, wenn er einen Stapelrahmen aufgebaut hat),
> da das im "Application Binary Interface" so definiert ist. Da
> das Win-64-ABI die Sicherung dieser Register vorschreibt (und
> minGW das auch so compiliert), kann es sich nur um ein Linux-
> Konstrukt handeln.
>
> Der verschwenderische Umgang mit Ressourcen war unter Anderem
> der Grund, weshalb ich (überzeugter Open-Source-Programierer)
> 2009 von OS/2 nicht auf Linux, sondern auf 64 Bit Windows um-
> gestiegen bin. Wenn nur sechs von 32 Registern (18,75%!) nach
> einem Aufruf den gleichen Wert wie davor haben, bedeutet das,
> dass ich 26 von 32 Registern (81,25%!) vor dem Aufruf sichern
> und anschliessend wieder vom Stapel laden muss. Bei Windows64
> wurde nur die Hälfte, also 13 von 32 Registern (40,625%), als
> "volatile" definiert, was gerade noch im Grenzbereich des Er-
> träglichen liegt.

Der Streit darüber, ob Caller-Save oder Callee-Save besser ist, ist alt.
Aus der Tatsache, dass er noch nicht entschieden ist, kann man
schließen, dass es keine allgemeingültige Antwort gibt.

Generell ist es in beiden Fällen unvermeidlich, dass Register
unnötigerweise gesichert werden. Bei Caller-Save muss der Caller das
Register vor dem Call sichern, wenn er nachher noch braucht, selbst wenn
das Register von der aufgerufenen Funktion nicht geändert wird (weil er
das eben nicht weiß). Umgekehrt muss bei Callee-Save der Callee ein
Register, dass er ändert, sichern, selbst wenn es vom Caller nach dem
Aufruf gar nicht mehr benötigt wird (weil er das eben nicht weiß).
Das ließe sich nur mit globaler Register-Allokation zur Linkzeit
verhindern, und selbst das geht nicht über Shared-Library-Grenzen
hinweg. In der Praxis teilt man daher das Registerfile in einen
Teil, für den der Callee zuständig ist und einen, für den der Caller
zuständig ist und überlässt es dem Compiler (oder dem
Assembler-Programmierer), die Register so zuzuweisen, dass die unnötigen
Saves minimiert werden.

Wie Microsoft und AMD (ich nehme an, dass das Unix AMD64 ABI von AMD
festgelegt wurden) bei der genauen Aufteilung angelangt sind, weiß ich
nicht. Ich würde aber annehmen, dass die ihren Hennessy & Patterson
gelesen haben und verschiedene Aufteilungen mit einer Auswahl relevanter
Programme und Libraries getestet haben.
Und wieviel dann jeweils addiert und subtrahiert wird, findet man nur
mehr durch die Analyse des Codes heraus (wenn es nicht woanders extra
abgelegt wird). Einen Stacktrace auszugeben, wird dann etwas mühsam.

Peter J. Holzer

unread,
Dec 13, 2014, 6:19:25 AM12/13/14
to
On 2014-12-08 15:59, Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>
>
>> On 2014-12-06 11:14, Bernhard Schornak <scho...@web.de> wrote:
>>> Peter J. Holzer schrieb:
>>>> On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
>>>>> Wer verwendet schon freiwillig CMPXCHG?
>>>>
>>>> Leute, die Locking-Primitives schreiben?
>>>
>>>
>>> Das hat zwar mit Assembler rein gar nix zu tun,
>>
>> Letztendlich muss es in Assembler implemetiert werden. Entweder in einer
>> Library oder durch den Compiler.
>
>
> Ja - mit der Kompetenz von HLL-Compilerbauern... ;)

Meiner Erfahrung nach ist es mit der Kompetenz von Leuten, die
routinemäßig alle anderen als inkompetent bezeichnen, meist nicht weit
her.


>> XCHG macht übrigens ein implizites LOCK, dürfte also nicht wesentlich
>> billiger sein als ein LOCK CMPXCHG.
>
>
> AMD : 5 Takte FP-Double statt 6/7 Takte Complex
> iNTEL: 1.5 (???) statt 5 Takte

1.5 Takte, wenn mit einer anderen CPU kommuniziert werden muss? Die
Zeitangabe bezieht sich wohl auf ein XCHG von zwei Registern im selben
Core, aber ganz sicher nicht auf einen Speicherzugriff.


>>> Wer viel will, muss viel dafür tun (oder an der Börse zocken) - ein
>>> paar zusätzliche Befehle braucht es sicher, um das zu realisieren.
>>
>> Mit "ein paar zusätzlichen Befehlen" werden Race-Conditions meistens
>> nicht besser.
>
>
> Je mehr Code, desto grösser die Verzögerung. Reicht meist aus,

... damit der Code nicht mehr beim Testen crasht, sondern erst in
Produktion, unter hoher Last und genau dann, wenn man es am wenigsten
brauchen kann. Das ist natürlich genau die Qualität, die man haben will.


>>>> Ich will nicht ausschließen, dass das theoretisch möglich ist, aber ich
>>>> glaube doch, dass sich die Intel-Leute was dabei gedacht haben, als sie
>>>> (mit dem 486er?) CMPXCHG eingeführt haben.
>>>
>>>
>>> http://en.wikipedia.org/wiki/Compare-and-swap
>>
>> | In the x86 (since 80486) and Itanium architectures this is implemented
>> | as the compare and exchange (CMPXCHG) instruction, though here the
>> | LOCK prefix should be there to make it really atomic.
>>
>> Wo ist da der Widerspruch?
>
>
> Welcher Widerspruch in Relation zu was?

Der Widerspruch zu meiner Mutmaßung, dass die Intel-Leute einen guten
Grund hatten, CMPXCHG einzuführen. Schließlich hast Du diesen Link
unmittelbar nach dieser Vermutung eingeworfen, also kann man wohl
erwarten, dass Du Dich darauf beziehst.

Der Artikel müsste also aussagen, dass CMPXCHG unnötig oder gar
kontraproduktiv ist. Tut er aber nicht, ganz im Gegenteil.


> Wer daran glaubt, dass eine Ausführungseinheit (Execution Pipe) in
> -einem- Taktzyklus -bis zu vier- Befehle ausgeführt werden können

Was hat denn das jetzt mit CMPXCHG zu tun?

> (das heisst: Es werden 4 Ergebnisse pro Takt geliefert!), der hat
> Physik durch Religion ersetzt.

Solche Architekturen nennt man superskalar, und sie existieren seit
Jahrzehnten. Die x86-Architektur ist seit dem Pentium ebenfalls
superskalar. Wieviele Instruktionen tatsächlich parallel abgearbeitet
werden, ist eine Frage des Aufwands (beim Pentium waren es nur 2), aber
zumindest bei einigen aktuellen Intel-Prozessoren sind es 4.

> Religion fordert Glauben statt Denken - ergo können die iNTELianer
> (wie alle guten Bewohner der USA!) nicht denken... ;)

Ich sehe den Smiley, aber hilft nicht.

Bernhard Schornak

unread,
Dec 13, 2014, 10:09:32 AM12/13/14
to
Peter J. Holzer schrieb:


> On 2014-12-08 15:59, Bernhard Schornak <scho...@web.de> wrote:
>> Peter J. Holzer schrieb:
>>> On 2014-12-06 11:14, Bernhard Schornak <scho...@web.de> wrote:
>>>> Peter J. Holzer schrieb:
>>>>> On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
>>
>>> XCHG macht übrigens ein implizites LOCK, dürfte also nicht wesentlich
>>> billiger sein als ein LOCK CMPXCHG.
>>
>> AMD : 5 Takte FP-Double statt 6/7 Takte Complex
>> iNTEL: 1.5 (???) statt 5 Takte
>
> 1.5 Takte, wenn mit einer anderen CPU kommuniziert werden muss? Die
> Zeitangabe bezieht sich wohl auf ein XCHG von zwei Registern im selben
> Core, aber ganz sicher nicht auf einen Speicherzugriff.


Oder auf neuartige Logikgatter, die bei steigenden und fallenden
Flanken des Taktsignals schalten. Möglicherweise ging es aber um
die Unterschiede zwischen XCHG und LOCK CMPXCHG, und die Angaben
geben ganz einfach die in den Datenbüchern angegebenen Takte an?


>> Wer daran glaubt, dass eine Ausführungseinheit (Execution Pipe) in
>> -einem- Taktzyklus -bis zu vier- Befehle ausgeführt werden können
>
> Was hat denn das jetzt mit CMPXCHG zu tun?


Das kann man oben nachlesen. Wenn das mit den Logikgattern keine
neue Erfindung von iNTEL ist, gibt es auch keine Befehle, die in
halben, drittel oder gar viertel Taktzyklen aus Prozessoren "ge-
pumpt" werden.


>> (das heisst: Es werden 4 Ergebnisse pro Takt geliefert!), der hat
>> Physik durch Religion ersetzt.
>
> Solche Architekturen nennt man superskalar, und sie existieren seit
> Jahrzehnten. Die x86-Architektur ist seit dem Pentium ebenfalls
> superskalar. Wieviele Instruktionen tatsächlich parallel abgearbeitet
> werden, ist eine Frage des Aufwands (beim Pentium waren es nur 2), aber
> zumindest bei einigen aktuellen Intel-Prozessoren sind es 4.


Es ging hier um vier Befehle pro Takt -und- pro Execution-Pipe -
die Taktangaben in einem Datenbuch beziehen sich -immer- auf die
Verarbeitung in einer Pipe, nicht auf den Durchsatz des gesamten
Kerns oder Prozessors.


Schönes Wochenende

Bernhard Schornak

Bernhard Schornak

unread,
Dec 13, 2014, 10:09:42 AM12/13/14
to
Peter J. Holzer schrieb:


> On 2014-12-09 14:54, Bernhard Schornak <scho...@web.de> wrote:
>> Jan Bruns schrieb:
>>> Bernhard Schornak:
>>>> Jan Bruns schrieb:
>>>>> Ich kann Dir grad gar nicht genau sagen, was für eine calling
>>>>> convention die Funktion verwendet.
>>>
>>>> Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
>>>> handeln.
>
> Das ist ein Fehlschluss.


Ach?

Im Bereich x86-64 gibt es nur zwei ABIs. Das andere, von
Microsoft definierte ABI schreibt das Sichern der beiden
hier nicht gesicherten Register vor.

Mir ist weder ein -drittes- x86-64-ABI noch ein weiteres
Prozessordesign bekannt, dass die für x86-64 definierten
Registernamen verwendet...


>>> cmpxchg %esi, (%rdi)
>>>
>>> verändert doch RDI und RSI gar nicht, also bräuchte auch dann
>>> nichts gesichert werden, wenn der callee die zu erhalten hätte.
>>
>> Das weiss der Compiler, der diese Sequenz erzeugt hatte, ganz
>> sicher nicht.
>
> Wenn der Sequenz von einem Compiler erzeugt wurde (ich halte es für
> nicht unwahrscheinlich, dass die handgeschrieben ist), dann weiß er das
> ziemlich sicher sehr wohl. Wie soll er denn Code erzeugen, wenn er nicht
> weiß, was eine Instruktion macht?


Weil "er" nur den Code abarbeitet, den "sein" "Erzeuger"
(ein Applikationsprogrammierer wie Du oder ich) "ihm" in
die Wiege gelegt hat. Es ist sehr unwahrscheinlich, dass
ein Compiler Instruktionen und ihre Parameter auf -mehr-
als die Einhaltung des gültigen Wertebereichs hin prüft,
respektive die Einhaltung der Syntax im Auge behält. Das
"Denken" bleibt weiterhin den Programmierern überlassen,
da Maschinen dazu (immer noch nicht...) fähig sind.


<schnipp>

> ...ich nehme an, dass das Unix AMD64 ABI von AMD festgelegt wurden...


Wie sollte das gehen? Unixderivate, darunter Linux, sind
Produkte etlicher "global Player". Ein Zwerg wie AMD ist
sicher nicht in der Lage, den Industriegiganten ihre ABI
aufzudrängen. Es gab eine Richtlinie von AMD, die später
in die System-V-ABI mit einfloss - die wurde aber sicher
nicht von AMD allein festgelegt...


Schönes Wochenende

Bernhard Schornak

Peter J. Holzer

unread,
Dec 13, 2014, 1:14:56 PM12/13/14
to
On 2014-12-13 15:09, Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>> On 2014-12-08 15:59, Bernhard Schornak <scho...@web.de> wrote:
>>> Peter J. Holzer schrieb:
>>>> On 2014-12-06 11:14, Bernhard Schornak <scho...@web.de> wrote:
>>>>> Peter J. Holzer schrieb:
>>>>>> On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
>>>
>>>> XCHG macht übrigens ein implizites LOCK, dürfte also nicht wesentlich
>>>> billiger sein als ein LOCK CMPXCHG.
>>>
>>> AMD : 5 Takte FP-Double statt 6/7 Takte Complex
>>> iNTEL: 1.5 (???) statt 5 Takte
>>
>> 1.5 Takte, wenn mit einer anderen CPU kommuniziert werden muss? Die
>> Zeitangabe bezieht sich wohl auf ein XCHG von zwei Registern im selben
>> Core, aber ganz sicher nicht auf einen Speicherzugriff.
>
>
> Oder auf neuartige Logikgatter, die bei steigenden und fallenden
> Flanken des Taktsignals schalten. Möglicherweise ging es aber um
> die Unterschiede zwischen XCHG und LOCK CMPXCHG, und die Angaben
> geben ganz einfach die in den Datenbüchern angegebenen Takte an?

Genau, es ging um den von Dir behaupteten und von mir bezweifelten
großen Performance-Unterschied zwischen XCHG und LOCK CMPXCHG. Dass Du
die 1.5 Takte einfach aus irgendeinem Datenblatt abgeschrieben hast,
glaube ich Dir sofort, aber nachgedacht hast Du dabei offensichtlich
nicht. Ein L1-Zugriff braucht bei einem Core i7 5500 4 Takte. Sowohl
XCHG als auch CMPXCHG brauchen zwei Zugriffe (einen Lese- und einen
Schreibzugriff), also geht unter 8 Takten gar nichts. Und da nehmen wir
schon großzügig an, dass die Cache-Invalidation auf den anderen
Prozessoren sich ebenfalls in der Zeit ausgeht, was ich (trotz QPI) eher
bezweifeln möchte. agner.org (die die ja auch schon zitiert hast),
listet für diese Instruktionen auf neueren Intel-Prozessoren Latenzen
von >= 20 Zyklen. Das scheint mir realistisch zu sein (im günstigsten
Fall: Wenn da wirklich auf RAM zugegriffen werden muss, womöglich noch
in einer anderen NUMA-Zone, wird das noch viel langsamer).


>>> Wer daran glaubt, dass eine Ausführungseinheit (Execution Pipe) in
>>> -einem- Taktzyklus -bis zu vier- Befehle ausgeführt werden können
>>
>> Was hat denn das jetzt mit CMPXCHG zu tun?
>
>
> Das kann man oben nachlesen.

Ach, dich stört der halbe Takt in der Angabe. Da ich nicht weiß, wo Du
den her hast, kann ich dazu auch nichts Definitives sagen. Lies selber
nach, was es zu bedeuten hat. Ich vermute mal, das ist der
durchschnittliche CPI-Wert unter idealen Bedingungen: Also wenn Du 100
XCHG reg,reg Instruktionen hintereinander ausführst, dann dauert das 150
Takte.


> Wenn das mit den Logikgattern keine neue Erfindung von iNTEL ist, gibt
> es auch keine Befehle, die in halben, drittel oder gar viertel
> Taktzyklen aus Prozessoren "ge- pumpt" werden.

Das hat auch außer Dir niemand angenommen.

(Theoretisch wäre es natürlich möglich, dass innerhalb eines Prozessors
einfache Schaltungen mit höherer Taktfrequenz laufen - aber Du kannst
Gift darauf nehmen, dass in dem Fall die Marketing-Abteilung natürlich
die höchste Frequenz als "Prozessorgeschwindigkeit" angibt).


>>> (das heisst: Es werden 4 Ergebnisse pro Takt geliefert!), der hat
>>> Physik durch Religion ersetzt.
>>
>> Solche Architekturen nennt man superskalar, und sie existieren seit
>> Jahrzehnten. Die x86-Architektur ist seit dem Pentium ebenfalls
>> superskalar. Wieviele Instruktionen tatsächlich parallel abgearbeitet
>> werden, ist eine Frage des Aufwands (beim Pentium waren es nur 2), aber
>> zumindest bei einigen aktuellen Intel-Prozessoren sind es 4.
>
> Es ging hier um vier Befehle pro Takt -und- pro Execution-Pipe -
> die Taktangaben in einem Datenbuch beziehen sich -immer- auf die
> Verarbeitung in einer Pipe, nicht auf den Durchsatz des gesamten
> Kerns oder Prozessors.

Die Taktangaben in einem Datenbuch sind generell mit Vorsicht zu
genießen und man sollte auch das Kleingedruckte lesen. Eine einzelne
Zahl wird auf keinem Prozessor, der in den letzten 20 Jahren erschienen
ist, das Zeitverhalten adäquat beschreiben.

Peter J. Holzer

unread,
Dec 13, 2014, 2:04:20 PM12/13/14
to
On 2014-12-13 15:09, Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>> On 2014-12-09 14:54, Bernhard Schornak <scho...@web.de> wrote:
>>> Jan Bruns schrieb:
>>>> Bernhard Schornak:
>>>>> Jan Bruns schrieb:
>>>>>> Ich kann Dir grad gar nicht genau sagen, was für eine calling
>>>>>> convention die Funktion verwendet.
>>>>
>>>>> Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
>>>>> handeln.
>>
>> Das ist ein Fehlschluss.
>
>
> Ach?

Ja.

> Im Bereich x86-64 gibt es nur zwei ABIs. Das andere, von
> Microsoft definierte ABI schreibt das Sichern der beiden
> hier nicht gesicherten Register vor.

Nein. Das ABI schreibt vor, dass der Callee für das Sichern dieser
Register verantwortlich ist. Aber wenn der Callee diese Register nicht
ändert, muss er sie natürlich auch nirgends hin sichern. Wozu sollte das
gut sein? Da hier die beiden Register nicht geändert werden, ist die
Funktion mit dem Microsoft-ABI kompatibel.


>>>> cmpxchg %esi, (%rdi)
>>>>
>>>> verändert doch RDI und RSI gar nicht, also bräuchte auch dann
>>>> nichts gesichert werden, wenn der callee die zu erhalten hätte.
>>>
>>> Das weiss der Compiler, der diese Sequenz erzeugt hatte, ganz
>>> sicher nicht.
>>
>> Wenn der Sequenz von einem Compiler erzeugt wurde (ich halte es für
>> nicht unwahrscheinlich, dass die handgeschrieben ist), dann weiß er das
>> ziemlich sicher sehr wohl. Wie soll er denn Code erzeugen, wenn er nicht
>> weiß, was eine Instruktion macht?
>
>
> Weil "er" nur den Code abarbeitet, den "sein" "Erzeuger"
> (ein Applikationsprogrammierer wie Du oder ich) "ihm" in
> die Wiege gelegt hat. Es ist sehr unwahrscheinlich, dass
> ein Compiler Instruktionen und ihre Parameter auf -mehr-
> als die Einhaltung des gültigen Wertebereichs hin prüft,
> respektive die Einhaltung der Syntax im Auge behält. Das
> "Denken" bleibt weiterhin den Programmierern überlassen,
> da Maschinen dazu (immer noch nicht...) fähig sind.

Es geht hier nicht darum, ob der Compiler irgendwie im philosophischen
Sinne "denkt", sondern darum, welche Informationen ihm für seine
Aufgabe zur Verfügung stehen. Und dazu gehört natürlich, welche Register
eine CPU hat, und welche Instruktion auf welche Register lesend und
schreibend zugreift. Für eine Multiplikation kann er z.B. "mul reg"
verwenden, um das tun zu können, muss er "wissen", dass der zweite
Operand in EAX stehen muss und dass das Ergebnis nachher in EDX:EAX
steht. Sonst kann er keinen Code erzeugen, der diese Instruktion
verwendet. Oder jedenfalls keinen auch nur annähernd optimalen.

Diese Information kann implizit im Programmcode des Compilers abgelegt
sein, sehr oft ist sie aber explizit - insbesondere bei Compilern wie
dem GCC, die Code für eine breite Palette verschiedener Prozessoren
erzeugen können.

>> ...ich nehme an, dass das Unix AMD64 ABI von AMD festgelegt wurden...
>
> Wie sollte das gehen? Unixderivate, darunter Linux, sind
> Produkte etlicher "global Player". Ein Zwerg wie AMD ist
> sicher nicht in der Lage, den Industriegiganten ihre ABI
> aufzudrängen.

Der Zwerg hat es auch geschafft, Intel seine ISA aufzudrängen, das finde
ich viel erstaunlicher, als dass ein Prozessorhersteller auch ein ABI
für seinen Prozessor festlegt.

Zur Frage wie das gehen soll: Einen Compiler zur Verfügung stellen. Wenn
der keine schwerwiegenden Mängel aufweist, werden den alle verwenden,
und damit ist das ABI defacto festgelegt. Im Nachhinein ändert man das
nicht mehr leicht, denn dann muss man ja kompatibel bleiben ...

AMD hat während der Entwicklung mit Microsoft und SuSE
zusammengearbeitet. Als der Prozessor auf den Markt kam, gab es sowohl
für Windows als auch für Linux funktionierende Compiler (und zumindest
im Fall von Linux sogar ein vollständig portiertes Betriebssystem).
Damit haben sie einfach Tatsachen geschaffen.

Interessant ist natürlich, dass die Calling-Conventions für Linux und
Windows doch recht deutlich voneinander abweichen. Das wird zum Teil
daran liegen, dass die von verschiedenen Teams festgelegt wurden (das
GCC-Team und das Microsoft-Team werden sicher nicht identisch gewesen
sein), zum Teil aber wahrscheinlich auch daran, dass der für die beiden
Betriebssysteme "typische" Code unterschiedlich war.

Bernhard Schornak

unread,
Dec 13, 2014, 6:54:31 PM12/13/14
to
Peter J. Holzer schrieb:


> On 2014-12-13 15:09, Bernhard Schornak <scho...@web.de> wrote:
>> Peter J. Holzer schrieb:
>>> On 2014-12-08 15:59, Bernhard Schornak <scho...@web.de> wrote:
>>>> Peter J. Holzer schrieb:
>>>>> On 2014-12-06 11:14, Bernhard Schornak <scho...@web.de> wrote:
>>>>>> Peter J. Holzer schrieb:
>>>>>>> On 2014-12-05 16:43, Bernhard Schornak <scho...@web.de> wrote:
>>>>
>>>>> XCHG macht übrigens ein implizites LOCK, dürfte also nicht wesentlich
>>>>> billiger sein als ein LOCK CMPXCHG.
>>>>
>>>> AMD : 5 Takte FP-Double statt 6/7 Takte Complex
>>>> iNTEL: 1.5 (???) statt 5 Takte
>>>
>>> 1.5 Takte, wenn mit einer anderen CPU kommuniziert werden muss? Die
>>> Zeitangabe bezieht sich wohl auf ein XCHG von zwei Registern im selben
>>> Core, aber ganz sicher nicht auf einen Speicherzugriff.
>>
>> Oder auf neuartige Logikgatter, die bei steigenden und fallenden
>> Flanken des Taktsignals schalten. Möglicherweise ging es aber um
>> die Unterschiede zwischen XCHG und LOCK CMPXCHG, und die Angaben
>> geben ganz einfach die in den Datenbüchern angegebenen Takte an?
>
> Genau, es ging um den von Dir behaupteten und von mir bezweifelten
> großen Performance-Unterschied zwischen XCHG und LOCK CMPXCHG. Dass Du
> die 1.5 Takte einfach aus irgendeinem Datenblatt abgeschrieben hast,
> glaube ich Dir sofort, aber nachgedacht hast Du dabei offensichtlich
> nicht.


Da es ebenso müssig ist wie das Kontemplieren über das Pinout
eines TTL-ICs? Selbst wenn man es wollte, könnte man -beides-
physikalisch nicht mehr ändern.


> Ein L1-Zugriff braucht bei einem Core i7 5500 4 Takte. Sowohl
> XCHG als auch CMPXCHG brauchen zwei Zugriffe (einen Lese- und einen
> Schreibzugriff), also geht unter 8 Takten gar nichts.


Dann sei bitte so lieb und bitte AMD / iNTEL, ihre "falschen"
Angaben in allen von ihnen publizierten Datenbüchern umgehend
zu ändern - ich bin der falsche Ansprechpartner.


>>>> Wer daran glaubt, dass eine Ausführungseinheit (Execution Pipe) in
>>>> -einem- Taktzyklus -bis zu vier- Befehle ausgeführt werden können
>>>
>>> Was hat denn das jetzt mit CMPXCHG zu tun?
>>
>> Das kann man oben nachlesen.
>
> Ach, dich stört der halbe Takt in der Angabe. Da ich nicht weiß, wo Du
> den her hast, kann ich dazu auch nichts Definitives sagen. Lies selber
> nach, was es zu bedeuten hat. Ich vermute mal, das ist der
> durchschnittliche CPI-Wert unter idealen Bedingungen: Also wenn Du 100
> XCHG reg,reg Instruktionen hintereinander ausführst, dann dauert das 150
> Takte.


Warum beschwerst Du Dich erst über falsche Angaben der Daten-
bücher, wenn Dir zwei Absätze später plötzlich (quer über den
Daumen geratene!) Angaben in "characters per inch" reichen?


>> Wenn das mit den Logikgattern keine neue Erfindung von iNTEL ist, gibt
>> es auch keine Befehle, die in halben, drittel oder gar viertel
>> Taktzyklen aus Prozessoren "ge- pumpt" werden.
>
> Das hat auch außer Dir niemand angenommen.


Du solltest vielleicht doch einmal in das "Intel 64 and IA-32
Architectures Software Developer’s Manual" - das Standardwerk,
das man als Assemblerprogrammierer rezitieren können müsste -
schauen?


> (Theoretisch wäre es natürlich möglich, dass innerhalb eines Prozessors
> einfache Schaltungen mit höherer Taktfrequenz laufen - aber Du kannst
> Gift darauf nehmen, dass in dem Fall die Marketing-Abteilung natürlich
> die höchste Frequenz als "Prozessorgeschwindigkeit" angibt).


Prozessoren, die bei Frequenzen jenseits 5 GHz laufen können,
sind mit der vorhandenen Lithographietechnik höchstens in La-
borstückzahlen produzierbar.


> Die Taktangaben in einem Datenbuch sind generell mit Vorsicht zu
> genießen und man sollte auch das Kleingedruckte lesen. Eine einzelne
> Zahl wird auf keinem Prozessor, der in den letzten 20 Jahren erschienen
> ist, das Zeitverhalten adäquat beschreiben.


Mit Deinem Expertenwissen kann ich als Programmierer diverser
in reinem Assembler verfasster Lowlevel-Testprogramme für die
Latenzen von Einzelbefehlen, die übrigens (zumindest bei AMD)
relativ genau mit den in Datenbüchern veröffentlichten Zahlen
übereinstimmen, natürlich nicht mithalten...


Schönes Wochenende

Bernhard Schornak

Bernhard Schornak

unread,
Dec 13, 2014, 6:54:58 PM12/13/14
to
Peter J. Holzer schrieb:


> On 2014-12-13 15:09, Bernhard Schornak <scho...@web.de> wrote:
>> Peter J. Holzer schrieb:
>>> On 2014-12-09 14:54, Bernhard Schornak <scho...@web.de> wrote:
>>>> Jan Bruns schrieb:
>>>>> Bernhard Schornak:
>>>>>> Jan Bruns schrieb:
>>>>>>> Ich kann Dir grad gar nicht genau sagen, was für eine calling
>>>>>>> convention die Funktion verwendet.
>>>>>
>>>>>> Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
>>>>>> handeln.
>>>
>>> Das ist ein Fehlschluss.
>>
>> Ach?
>
> Ja.
>
>> Im Bereich x86-64 gibt es nur zwei ABIs. Das andere, von
>> Microsoft definierte ABI schreibt das Sichern der beiden
>> hier nicht gesicherten Register vor.
>
> Nein. Das ABI schreibt vor, dass der Callee für das Sichern dieser
> Register verantwortlich ist. Aber wenn der Callee diese Register nicht
> ändert, muss er sie natürlich auch nirgends hin sichern. Wozu sollte das
> gut sein? Da hier die beiden Register nicht geändert werden, ist die
> Funktion mit dem Microsoft-ABI kompatibel.


Dann müsste es aber

cmpxchg %edx, (%rcx)

heissen, da laut Windows-ABI die ersten zwei Parameter in RCX
und RDX übergeben werden.

Wir könnten jetzt natürlich noch annehmen, dass der Verfasser
des Codes die Parameter direkt in den Registern übergibt, und
die Funktion ohne Parameter aufgerufen wird. Damit wäre diese
Funktion jedoch sowohl in 64 Bit Windows als auch Linux -nur-
von Assemblerfunktionen ansprechbar, da diese Parameter ja in
die zwei Register geschrieben werden müssten. Mit den Aufruf-
konventionen gängiger "Hochsprachen" wäre das nicht unbedingt
kompatibel. Assemblerprogrammierer benötigen auch keine Funk-
tionen, um die Ausführung eines einzelnen Assemblerbefehls in
einer "Hochsprache" zu ermöglichen...


>>> Wenn der Sequenz von einem Compiler erzeugt wurde (ich halte es für
>>> nicht unwahrscheinlich, dass die handgeschrieben ist), dann weiß er das
>>> ziemlich sicher sehr wohl. Wie soll er denn Code erzeugen, wenn er nicht
>>> weiß, was eine Instruktion macht?
>>
>> Weil "er" nur den Code abarbeitet, den "sein" "Erzeuger"
>> (ein Applikationsprogrammierer wie Du oder ich) "ihm" in
>> die Wiege gelegt hat. Es ist sehr unwahrscheinlich, dass
>> ein Compiler Instruktionen und ihre Parameter auf -mehr-
>> als die Einhaltung des gültigen Wertebereichs hin prüft,
>> respektive die Einhaltung der Syntax im Auge behält. Das
>> "Denken" bleibt weiterhin den Programmierern überlassen,
>> da Maschinen dazu (immer noch nicht...) fähig sind.
>
> Es geht hier nicht darum, ob der Compiler irgendwie im philosophischen
> Sinne "denkt", sondern darum, welche Informationen ihm für seine
> Aufgabe zur Verfügung stehen. Und dazu gehört natürlich, welche Register
> eine CPU hat, und welche Instruktion auf welche Register lesend und
> schreibend zugreift. Für eine Multiplikation kann er z.B. "mul reg"
> verwenden, um das tun zu können, muss er "wissen", dass der zweite
> Operand in EAX stehen muss und dass das Ergebnis nachher in EDX:EAX
> steht. Sonst kann er keinen Code erzeugen, der diese Instruktion
> verwendet. Oder jedenfalls keinen auch nur annähernd optimalen.


Du verwechselst die Überprüfung von Parametern oder ihrer An-
ordnung innerhalb des Befehls mit der Analyse des "Sinns oder
Zwecks" ganzer Befehlsfolgen (= Funktionen).


> Diese Information kann implizit im Programmcode des Compilers abgelegt
> sein, sehr oft ist sie aber explizit - insbesondere bei Compilern wie
> dem GCC, die Code für eine breite Palette verschiedener Prozessoren
> erzeugen können.


Die Eigenheiten der Prozessoren sind in maschinenspezifischen
Dateien festgehalten. Ich habe früher immer die fehlenden Be-
fehle manuell dazugefügt und meinen "eigenen" GCC kompiliert,
das ist aber seit etlichen Jahren nicht mehr möglich, da nach
einigen Umstellungen alle Dateien so gut versteckt sind, dass
man sie nicht mehr findet.


>>> ...ich nehme an, dass das Unix AMD64 ABI von AMD festgelegt wurden...
>>
>> Wie sollte das gehen? Unixderivate, darunter Linux, sind
>> Produkte etlicher "global Player". Ein Zwerg wie AMD ist
>> sicher nicht in der Lage, den Industriegiganten ihre ABI
>> aufzudrängen.
>
> Der Zwerg hat es auch geschafft, Intel seine ISA aufzudrängen, das finde
> ich viel erstaunlicher, als dass ein Prozessorhersteller auch ein ABI
> für seinen Prozessor festlegt.


Okay. Ich hatte gelernt, dass ISA zusammen mit dem PC von IBM
eingeführt wurde. Offenbar hat AMD trotz geringem Marktanteil
die gesamte Computerindustrie fest in der Hand?


> Zur Frage wie das gehen soll: Einen Compiler zur Verfügung stellen. Wenn
> der keine schwerwiegenden Mängel aufweist, werden den alle verwenden,
> und damit ist das ABI defacto festgelegt. Im Nachhinein ändert man das
> nicht mehr leicht, denn dann muss man ja kompatibel bleiben ...


Im Gegensatz zu iNTEL vertreibt AMD keinen eigenen Compiler -
was AMD bei gängigen Benchmarks laufend zu spüren bekommt...


> Interessant ist natürlich, dass die Calling-Conventions für Linux und
> Windows doch recht deutlich voneinander abweichen. Das wird zum Teil
> daran liegen, dass die von verschiedenen Teams festgelegt wurden (das
> GCC-Team und das Microsoft-Team werden sicher nicht identisch gewesen
> sein), zum Teil aber wahrscheinlich auch daran, dass der für die beiden
> Betriebssysteme "typische" Code unterschiedlich war.


Es mag daran liegen, dass Windows als Stand-Alone-System kon-
zipiert war, während Linux als UNIX-Derivat für vernetzte Ar-
beitsplätze entwickelt wurde. Je nach Aufgabenstellung ergibt
sich ein recht unterschiedlicher Aufbau der Software, die das
bewerkstelligt.


Schönes Wochenende

Bernhard Schornak

Peter J. Holzer

unread,
Dec 14, 2014, 8:53:10 AM12/14/14
to
Vom Ändern redet ja auch niemand, nur vom Verstehen. Dass sich 1.5 Takte
bei zwei Memory-Zugriffen (selbst wenn es nur auf den L1-Cache ist)
nicht ausgehen können, sollte jedem klar sein, der auch nur ein bisschen
eine Ahnung von Prozessorarchitekturen hat.


>> Ein L1-Zugriff braucht bei einem Core i7 5500 4 Takte. Sowohl
>> XCHG als auch CMPXCHG brauchen zwei Zugriffe (einen Lese- und einen
>> Schreibzugriff), also geht unter 8 Takten gar nichts.
>
>
> Dann sei bitte so lieb und bitte AMD / iNTEL, ihre "falschen"
> Angaben in allen von ihnen publizierten Datenbüchern umgehend
> zu ändern - ich bin der falsche Ansprechpartner.

Du hast ja keine Quellen angegeben, daher kann ich das nicht einmal
überprüfen. Vielleicht liegt das Problem ja eher beim Leser als beim
Buch?

Kleines Beispiel: In meinem 8086er-Buch (der 8086 ist ungefähr zu der
Zeit erschienen, als Du mit Assembler gegonnen hast, vielleicht liegt
Dir der mehr) stehen (über 4 Seiten verteil) drei verschiedene
Ausführungszeiten für XCHG:

3 Takte (für XCHG AX, reg)
4 Takte (für XCHG reg, reg)
17+EA Takte (für XCHG reg/mem, reg/mem)

Wenn ich da übersehe, dass die erste Angabe nur für die einfachste Form
von XCHG steht und nicht umblättere, dann glaube ich vielleicht, dass
der 8086 einen Wert in einem Register mit einem im Memory in 3 Takten
austauschen konnte. Konnte er natürlich nicht (auch das musste damals
jedem halbwegs kompetenten Programmierer klar sein), die richtige Angabe
für diesen Fall war 17+EA Takte (und wieviel EA war, hing natürlich vom
RAM ab).


>>>>> Wer daran glaubt, dass eine Ausführungseinheit (Execution Pipe) in
>>>>> -einem- Taktzyklus -bis zu vier- Befehle ausgeführt werden können
>>>>
>>>> Was hat denn das jetzt mit CMPXCHG zu tun?
>>>
>>> Das kann man oben nachlesen.
>>
>> Ach, dich stört der halbe Takt in der Angabe. Da ich nicht weiß, wo Du
>> den her hast, kann ich dazu auch nichts Definitives sagen. Lies selber
>> nach, was es zu bedeuten hat. Ich vermute mal, das ist der
>> durchschnittliche CPI-Wert unter idealen Bedingungen: Also wenn Du 100
>> XCHG reg,reg Instruktionen hintereinander ausführst, dann dauert das 150
>> Takte.
>
>
> Warum beschwerst Du Dich erst über falsche Angaben der Daten-
> bücher,

Ich beschwere mich gar nicht über falsche Angaben, ich bezweifle nur,
dass Deine Interpretation richtig ist. Die Angabe ist fast sicher
richtig, Du musst nur nachlesen, was sie bedeutet.

> wenn Dir zwei Absätze später plötzlich (quer über den
> Daumen geratene!) Angaben in "characters per inch" reichen?

"Clock cycles per instruction" natürlich. Unter welchem Stein hast Du
Dich die letzten 35 Jahre verkrochen?


>>> Wenn das mit den Logikgattern keine neue Erfindung von iNTEL ist, gibt
>>> es auch keine Befehle, die in halben, drittel oder gar viertel
>>> Taktzyklen aus Prozessoren "ge- pumpt" werden.
>>
>> Das hat auch außer Dir niemand angenommen.
>
>
> Du solltest vielleicht doch einmal in das "Intel 64 and IA-32
> Architectures Software Developer’s Manual" - das Standardwerk,
> das man als Assemblerprogrammierer rezitieren können müsste -
> schauen?

Wie gesagt, ich bezweifle, dass Du den Inhalt richtig interpretierst.


>> (Theoretisch wäre es natürlich möglich, dass innerhalb eines Prozessors
>> einfache Schaltungen mit höherer Taktfrequenz laufen - aber Du kannst
>> Gift darauf nehmen, dass in dem Fall die Marketing-Abteilung natürlich
>> die höchste Frequenz als "Prozessorgeschwindigkeit" angibt).
>
>
> Prozessoren, die bei Frequenzen jenseits 5 GHz laufen können,
> sind mit der vorhandenen Lithographietechnik höchstens in La-
> borstückzahlen produzierbar.

Naja, einfache Schaltungen gehen durchaus schneller als ein ganzer
Prozessor. Aber wie gesagt, wenn Intel das machen würde, würde sich die
Marketingabteilung sofort darauf werfen. Also kann man mit 99%iger
Sicherheit davon ausgehen, dass sie es nicht machen.

Peter J. Holzer

unread,
Dec 14, 2014, 9:53:37 AM12/14/14
to
On 2014-12-13 23:55, Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>> On 2014-12-13 15:09, Bernhard Schornak <scho...@web.de> wrote:
>>> Peter J. Holzer schrieb:
>>>> On 2014-12-09 14:54, Bernhard Schornak <scho...@web.de> wrote:
>>>>> Jan Bruns schrieb:
>>>>>> Bernhard Schornak:
>>>>>>> Da RDI und RSI nicht gesichert werden, kann es sich nur um Linux
>>>>>>> handeln.
>>>>
>>>> Das ist ein Fehlschluss.
>>>
>>> Ach?
>>
>> Ja.
>>
>>> Im Bereich x86-64 gibt es nur zwei ABIs. Das andere, von
>>> Microsoft definierte ABI schreibt das Sichern der beiden
>>> hier nicht gesicherten Register vor.
>>
>> Nein. Das ABI schreibt vor, dass der Callee für das Sichern dieser
>> Register verantwortlich ist. Aber wenn der Callee diese Register nicht
>> ändert, muss er sie natürlich auch nirgends hin sichern. Wozu sollte das
>> gut sein? Da hier die beiden Register nicht geändert werden, ist die
>> Funktion mit dem Microsoft-ABI kompatibel.
>
>
> Dann müsste es aber
>
> cmpxchg %edx, (%rcx)
>
> heissen, da laut Windows-ABI die ersten zwei Parameter in RCX
> und RDX übergeben werden.

Das ist ein Argument (%edi und %esi sind die beiden ersten
Integer-Parameter im Linux-ABI, das passt also ebenfalls zusammen).
Selbst die Syntax des (Dis-)Assemblers (GNU-Syntax, nicht MS-Syntax)
wäre ein Argument gewesen, wenn auch ein eher schwaches.

Aber aus der Tatsache, dass ein Register, das gar nicht geändert wird,
nicht gesichert wird, kannst Du eben keinen Schluss ziehen.
Diese Optimierung kann jeder Compiler durchführen, und ein menschlicher
Programmierer erst recht (ich hoffe sehr, dass Du in Deinem eigenen
Code, nicht Register völlig unnötig irgendwohin speicherst).

[Arbeitsweise eines Compilers]

> Du verwechselst die Überprüfung von Parametern oder ihrer An-
> ordnung innerhalb des Befehls mit der Analyse des "Sinns oder
> Zwecks" ganzer Befehlsfolgen (= Funktionen).

Nein. Aber gut, dass Du unten erwähnst, dass Du die Interna des GCC eh
kennst, so kann ich mir sparen, das zu erklären. Wie Deine zur Schau
gestellte Unkenntnis damit zusammenpasst, verstehe ich allerdings
nicht.


>>>> ...ich nehme an, dass das Unix AMD64 ABI von AMD festgelegt wurden...
>>>
>>> Wie sollte das gehen? Unixderivate, darunter Linux, sind
>>> Produkte etlicher "global Player". Ein Zwerg wie AMD ist
>>> sicher nicht in der Lage, den Industriegiganten ihre ABI
>>> aufzudrängen.
>>
>> Der Zwerg hat es auch geschafft, Intel seine ISA aufzudrängen, das finde
>> ich viel erstaunlicher, als dass ein Prozessorhersteller auch ein ABI
>> für seinen Prozessor festlegt.
>
>
> Okay. Ich hatte gelernt, dass ISA zusammen mit dem PC von IBM
> eingeführt wurde.

ISA = Instruction Set Architecture
nicht zu verwechseln mit
ISA = Industry Standard Architecture (dem AT-Bus)

Du solltest wirklich versuchen, sinnerfassend zu lesen. Wenn wir von
Prozessorarchitekturen reden, heißt CPI ganz sicher nicht "characters
per inch" und es ist auch eher unwahrscheinlich, dass mit ISA ein
damals schon recht veraltetes Bussystem gemeint ist.

> Offenbar hat AMD trotz geringem Marktanteil die gesamte
> Computerindustrie fest in der Hand?

Quatsch. Aber Intel hat das 64-Bit Instruction Set eben von AMD
übernommen und seine eigene 64-Bit-Architektur praktisch aufgegeben.

Daran gibt es nichts herumzudeuteln. Dass Intel dann auch wieder
aufgeholt und heute auch bei 64-Bit-Prozessoren einen wesentlich
größeren Marktanteil als AMD hat, ist ebenso Tatsache. Aber die
Innovation kam von AMD.

>> Zur Frage wie das gehen soll: Einen Compiler zur Verfügung stellen. Wenn
>> der keine schwerwiegenden Mängel aufweist, werden den alle verwenden,
>> und damit ist das ABI defacto festgelegt. Im Nachhinein ändert man das
>> nicht mehr leicht, denn dann muss man ja kompatibel bleiben ...
>
>
> Im Gegensatz zu iNTEL vertreibt AMD keinen eigenen Compiler -
> was AMD bei gängigen Benchmarks laufend zu spüren bekommt...

Dafür haben sie eben mit SuSE und Microsoft zusammengearbeitet: SuSE hat
ein Backend für den GCC (C, C++, Fortran) erstellt, MS eines für Visual
C++. (Und natürlich war die Zusammenarbeit mit MS auch wichtig, weil sie
so den Source-Code für Windows bekommen haben: Wenn Du einen neuen
Prozessor entwickelst, dann willst Du die Betriebssysteme, die darauf
laufen sollen, compilieren können, *bevor* der Prozessor fertig ist.)

Der GCC für x86_64 erzeugt sicher schlechteren Code als der
Intel-Compiler. Aber er war *verfügbar*, bevor es den Prozessor
überhaupt gab. Und damit wurde das von dieser speziellen Portierung des
GCC vorgebene ABI eben zum Standard. Jedes davon abweichende ABI hätte
substanzielle Verbesserungen nachweisen müssen, um das bereits
etablierte noch ablösen zu können. Kompatibilität schlägt Performance.

Bernhard Schornak

unread,
Dec 14, 2014, 2:11:55 PM12/14/14
to
Irgendwie reden wir aneinander vorbei. Ich habe mit selbstgebauten
TTL-Schaltungen begonnen, als es noch keinen erschwinglichen Heim-
computer gab. Das erste, grundlegende Prinzip jeder Logikschaltung
ist der Takt (Schaltzyklus) als kleinstmögliche Einheit: Die Zeit,
die zwischen je zwei aufeinander folgenden Ein- oder Ausschaltvor-
gängen vergeht. Der Weitertransport von Signalen zwischen zwei wie
auch immer beschaffenen Einheiten erfolgt immer mit der steigenden
(oder fallenden bei Active-Low-Logik) Flanke. Während der entgegen
gesetzten Flanke (fallend oder steigend) passiert hingegen nichts,
da die Elektronik nur auf eine Flanke reagieren kann.

Prozessoren basieren auf den gleichen Grundlagen. Es gibt - meines
Wissens - kein einziges Prozessordesign, das auf beide Flanken re-
agiert, um zwei Signale pro Takt generieren zu können.

Von dieser Warte her sind mir iNTELs Angaben suspekt - und wesent-
lich mehr als das hatte ich bislang auch nicht geäussert.


>>> Ein L1-Zugriff braucht bei einem Core i7 5500 4 Takte. Sowohl
>>> XCHG als auch CMPXCHG brauchen zwei Zugriffe (einen Lese- und einen
>>> Schreibzugriff), also geht unter 8 Takten gar nichts.
>>
>> Dann sei bitte so lieb und bitte AMD / iNTEL, ihre "falschen"
>> Angaben in allen von ihnen publizierten Datenbüchern umgehend
>> zu ändern - ich bin der falsche Ansprechpartner.
>
> Du hast ja keine Quellen angegeben, daher kann ich das nicht einmal
> überprüfen. Vielleicht liegt das Problem ja eher beim Leser als beim
> Buch?


Zum "Handwerkszeug" jedes Assemblerprogrammierers gehören aktuelle
"Optimisation Guides" der Prozessorhersteller, in denen in der Re-
gel auch Abarbeitungszeiten (Latencies) der einzelnen Befehle ent-
halten sind. Da ich in einer Newsgruppe für Assemblerprogrammierer
poste, darf ich davon ausgehen, dass die Grundlagen bekannt sind.


>>>>>> Wer daran glaubt, dass eine Ausführungseinheit (Execution Pipe) in
>>>>>> -einem- Taktzyklus -bis zu vier- Befehle ausgeführt werden können
>>>>>
>>>>> Was hat denn das jetzt mit CMPXCHG zu tun?
>>>>
>>>> Das kann man oben nachlesen.
>>>
>>> Ach, dich stört der halbe Takt in der Angabe. Da ich nicht weiß, wo Du
>>> den her hast, kann ich dazu auch nichts Definitives sagen. Lies selber
>>> nach, was es zu bedeuten hat. Ich vermute mal, das ist der
>>> durchschnittliche CPI-Wert unter idealen Bedingungen: Also wenn Du 100
>>> XCHG reg,reg Instruktionen hintereinander ausführst, dann dauert das 150
>>> Takte.
>>
>> Warum beschwerst Du Dich erst über falsche Angaben der Daten-
>> bücher,
>
> Ich beschwere mich gar nicht über falsche Angaben, ich bezweifle nur,
> dass Deine Interpretation richtig ist. Die Angabe ist fast sicher
> richtig, Du musst nur nachlesen, was sie bedeutet.


Wie bereits gesagt: Es ist müssig, sich über veröffentlichte Daten
den Kopf zu zerbrechen. Wenn ich mit meinen eigenen Testprogrammen
die Latenzen von zwanzig oder dreissig Befehlen bestätigen konnte,
dürften die restlichen Angaben mit grosser Wahrscheinlichkeit auch
korrekt sein. Andererseits hatte ich (überzeugter "iNTEL OUTSIDE"-
Fan) noch keinen PC, in dem ein iNTEL-Prozessor arbeitete. Deshalb
habe ich von iNTEL-Produkten keine Vergleichsdaten, und kann daher
keine Angaben zu deren Ausführungszeiten machen. Als Elektronikfan
lassen Angaben mit Null-Komma-Irgendwas Taktzyklen bei mir besten-
falls die Alarmglocken läuten...

Deinen Vorwurf bezüglich des Nicht-Verstehens von Datenbüchern ig-
noriere ich ganz einfach...


>> wenn Dir zwei Absätze später plötzlich (quer über den
>> Daumen geratene!) Angaben in "characters per inch" reichen?
>
> "Clock cycles per instruction" natürlich. Unter welchem Stein hast Du
> Dich die letzten 35 Jahre verkrochen?


Gegenfrage: In welcher Wortdesign-Werkstätte arbeitest Du?

Beim Gurgeln stosse ich auf

- Characters Per Inch
- Consumer Price Index
- Corruption Perception Index
- California Psychological Inventory
- Crane Payment Innovations

und viele andere, aber kein "Clock cycles per instruction" (was in
korrekter Form auch zu CCPI abgekürzt würde)...

Wenn Du schon neue Begriffe erfindest, würde eine Erklärung sicher
zum Verständnis Deiner Antworten beitragen.


>>>> Wenn das mit den Logikgattern keine neue Erfindung von iNTEL ist, gibt
>>>> es auch keine Befehle, die in halben, drittel oder gar viertel
>>>> Taktzyklen aus Prozessoren "ge- pumpt" werden.
>>>
>>> Das hat auch außer Dir niemand angenommen.
>>
>> Du solltest vielleicht doch einmal in das "Intel 64 and IA-32
>> Architectures Software Developer’s Manual" - das Standardwerk,
>> das man als Assemblerprogrammierer rezitieren können müsste -
>> schauen?
>
> Wie gesagt, ich bezweifle, dass Du den Inhalt richtig interpretierst.


Was - mit Verlaub - Dein Problem ist.


>>> (Theoretisch wäre es natürlich möglich, dass innerhalb eines Prozessors
>>> einfache Schaltungen mit höherer Taktfrequenz laufen - aber Du kannst
>>> Gift darauf nehmen, dass in dem Fall die Marketing-Abteilung natürlich
>>> die höchste Frequenz als "Prozessorgeschwindigkeit" angibt).
>>
>> Prozessoren, die bei Frequenzen jenseits 5 GHz laufen können,
>> sind mit der vorhandenen Lithographietechnik höchstens in La-
>> borstückzahlen produzierbar.
>
> Naja, einfache Schaltungen gehen durchaus schneller als ein ganzer
> Prozessor.


Es geht hier um Prozessoren, nicht um die in Satelliten und Radar-
geräte eingesetzte Elektronik, die /hochfrequenzseitig/ immer noch
auf analoger Basis arbeitet - ein mit 60 GHz betriebener Prozessor
ist auf absehbare Zeit nicht realisierbar.


> Aber wie gesagt, wenn Intel das machen würde, würde sich die
> Marketingabteilung sofort darauf werfen. Also kann man mit 99%iger
> Sicherheit davon ausgehen, dass sie es nicht machen.


Wie bereits angesprochen könnte man den Datendurchsatz verdoppeln,
wenn man die Möglichkeit fände, sowohl bei steigenden als auch bei
fallenden Taktflanken eine Aktion zu triggern. Das muss eine Firma
nicht zwangsläufig an die grosse Glocke hängen, wenn sie möglichst
lange die zwangsläufig auftretenden "Nachahmer" auf Distanz halten
möchte...

Bernhard Schornak

unread,
Dec 14, 2014, 2:12:03 PM12/14/14
to
Peter J. Holzer schrieb:


> On 2014-12-13 23:55, Bernhard Schornak <scho...@web.de> wrote:
>> Peter J. Holzer schrieb:
>>> On 2014-12-13 15:09, Bernhard Schornak <scho...@web.de> wrote:
>>>> Peter J. Holzer schrieb:
>>>>> On 2014-12-09 14:54, Bernhard Schornak <scho...@web.de> wrote:
>>>>>> Jan Bruns schrieb:
>>>>>>> Bernhard Schornak:
>
>>>>> ...ich nehme an, dass das Unix AMD64 ABI von AMD festgelegt wurden...
>>>>
>>>> Wie sollte das gehen? Unixderivate, darunter Linux, sind
>>>> Produkte etlicher "global Player". Ein Zwerg wie AMD ist
>>>> sicher nicht in der Lage, den Industriegiganten ihre ABI
>>>> aufzudrängen.
>>>
>>> Der Zwerg hat es auch geschafft, Intel seine ISA aufzudrängen, das finde
>>> ich viel erstaunlicher, als dass ein Prozessorhersteller auch ein ABI
>>> für seinen Prozessor festlegt.
>>
>> Okay. Ich hatte gelernt, dass ISA zusammen mit dem PC von IBM
>> eingeführt wurde.
>
> ISA = Instruction Set Architecture
> nicht zu verwechseln mit
> ISA = Industry Standard Architecture (dem AT-Bus)
>
> Du solltest wirklich versuchen, sinnerfassend zu lesen. Wenn wir von
> Prozessorarchitekturen reden, heißt CPI ganz sicher nicht "characters
> per inch" und es ist auch eher unwahrscheinlich, dass mit ISA ein
> damals schon recht veraltetes Bussystem gemeint ist.


Ich kann zwar bruchstückhafte Sätze interpolieren, um ihnen
einen Sinn abzuringen. Bei Abkürzungen, die für den grossen
Teil der Menschheit eine bekannte Bedeutung haben, die dann
von einer Minderheit neu definiert wird, sollte man bei der
Verwendung von alternativen Bedeutungen nicht darauf bauen,
dass anderen Lesern die neue(n) Definition(en) bekannt ist/
sind.

Wer im Bereich Computertechnik nach den von Dir verwendeten
Abkürzungen gurgelt, wird auf den ersten fünf Seiten keinen
einzigen Treffer mit den von Dir nachgereichten Bedeutungen
finden. Wenn Du schon selbstgestrickte Abkürzungen ins Feld
führst, solltest Du ihre Bedeutung zumindest bei der ersten
Verwendung in Klammern dazu schreiben.


>> Offenbar hat AMD trotz geringem Marktanteil die gesamte
>> Computerindustrie fest in der Hand?
>
> Quatsch. Aber Intel hat das 64-Bit Instruction Set eben von AMD
> übernommen und seine eigene 64-Bit-Architektur praktisch aufgegeben.


Dass IA64-Prozessoren nicht mehr auf dem Consumermarkt ver-
trieben werden, heisst nicht, dass iNTEL diese Familie ganz
aufgegeben hat. Sie wird in anderen Marktsegmenten durchaus
noch verwendet und meines Wissens immer noch produziert.

Volker Birk

unread,
Dec 14, 2014, 2:48:44 PM12/14/14
to
Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>> ISA = Instruction Set Architecture […]
>> CPI
> […]
> Wer im Bereich Computertechnik nach den von Dir verwendeten
> Abkürzungen gurgelt, wird auf den ersten fünf Seiten keinen
> einzigen Treffer mit den von Dir nachgereichten Bedeutungen
> finden.

https://en.wikipedia.org/wiki/Instruction_set
https://en.wikipedia.org/wiki/Cycles_per_instruction

Was Peter hier referenziert, ist in dieser Gruppe on-topic.

>> Aber Intel hat das 64-Bit Instruction Set eben von AMD
>> übernommen und seine eigene 64-Bit-Architektur praktisch aufgegeben.
> Dass IA64-Prozessoren nicht mehr auf dem Consumermarkt ver-
> trieben werden, heisst nicht, dass iNTEL diese Familie ganz
> aufgegeben hat. Sie wird in anderen Marktsegmenten durchaus
> noch verwendet und meines Wissens immer noch produziert.

Das ändert nichts an der Richtigkeit von Peters Ausführungen. In
letzter Zeit mal was von Kittson gehört? Nein? Ich auch nicht.

Viele Grüsse,
VB.
--
“Vor Snowden war das ein Blog mit Verschwörungstheorien.
Nach Snowden ist das ein Security-Newsticker.
Bei unverändertem Inhalt...”
Marc Stibane über Fefes Blog

Peter J. Holzer

unread,
Dec 14, 2014, 3:17:22 PM12/14/14
to
On 2014-12-14 19:12, Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>> On 2014-12-13 23:54, Bernhard Schornak <scho...@web.de> wrote:
>>> Peter J. Holzer schrieb:
>>>> On 2014-12-13 15:09, Bernhard Schornak <scho...@web.de> wrote:
>>>>> Peter J. Holzer schrieb:
>>>>>> On 2014-12-08 15:59, Bernhard Schornak <scho...@web.de> wrote:
>>>>>>> Peter J. Holzer schrieb:
>>>>>>>> XCHG macht übrigens ein implizites LOCK, dürfte also nicht wesentlich
>>>>>>>> billiger sein als ein LOCK CMPXCHG.
>>>>>>>
>>>>>>> AMD : 5 Takte FP-Double statt 6/7 Takte Complex
>>>>>>> iNTEL: 1.5 (???) statt 5 Takte
>>>>>>
>>>>>> 1.5 Takte, wenn mit einer anderen CPU kommuniziert werden muss? Die
>>>>>> Zeitangabe bezieht sich wohl auf ein XCHG von zwei Registern im selben
>>>>>> Core, aber ganz sicher nicht auf einen Speicherzugriff.
[...]
>>
>> Vom Ändern redet ja auch niemand, nur vom Verstehen. Dass sich 1.5 Takte
>> bei zwei Memory-Zugriffen (selbst wenn es nur auf den L1-Cache ist)
>> nicht ausgehen können, sollte jedem klar sein, der auch nur ein bisschen
>> eine Ahnung von Prozessorarchitekturen hat.
>
>
> Irgendwie reden wir aneinander vorbei.

Ja, ich merke es. Du hängst Dich daran auf, dass da keine ganze Zahl
steht. Mir ist das hingegen ziemlich egal, erstens weil es ein
Durchschnitt sein könnte, und zweitens weil Du mit fast 100%-iger
Sicherheit die falsche Zahl zitiert hast. Ob da 1, 1.5 oder 2 Takte
steht - es ist garantiert falsch für einen Memory-Zugriff. Eine
Abweichung von 0.5 ist vollkommen belanglos, wenn der wahre Fehler
wahrscheinlich eher bei 20 liegt.

Damit bleibt mir nur noch "386" zu sagen, und damit meine ich auch nicht
den Intel-Prozessor :-).

Bernhard Schornak

unread,
Dec 15, 2014, 9:50:58 AM12/15/14
to
Volker Birk schrieb:


> Bernhard Schornak <scho...@web.de> wrote:
>> Peter J. Holzer schrieb:
>>> ISA = Instruction Set Architecture […]
>>> CPI
>> […]
>> Wer im Bereich Computertechnik nach den von Dir verwendeten
>> Abkürzungen gurgelt, wird auf den ersten fünf Seiten keinen
>> einzigen Treffer mit den von Dir nachgereichten Bedeutungen
>> finden.
>
> https://en.wikipedia.org/wiki/Instruction_set


In der verlinkten deutschen Version des obigen Artikels

https://de.wikipedia.org/wiki/Befehlssatz

wird die Abkürzung ISA nirgendwo erwähnt. Auch dieser Artikel

> https://en.wikipedia.org/wiki/Cycles_per_instruction

ist nur in einer englischen Version verfügbar. Ich sollte ihn
-möglicherweise- kennen, so lange ich in c.l.a.x86 oder a.l.a
diskutiere, im deutschsprachigen Raum sind diesen Abkürzungen
aber eindeutig den ursprünglichen Bedeutungen (wie von mir in
früheren Postings bereits ausgeführt) zugeordnet.


> Was Peter hier referenziert, ist in dieser Gruppe on-topic.


-Das- stand auch niemals zur Debatte. Es ging ausschliesslich
um - ausschliesslich im englischsprachigen Raum - mehrdeutige
Abkürzungen. Im deutschsprachigen Raum haben ISA und CPI seit
je her die ursprüngliche Bedeutung, da sich die Mehrfachdefi-
nitionen nicht durchsetzen konnten. In Deutschland wären

BSA = BefehlsSatz-Architektur

und

TPB = Taktzyklen pro Befehl

unverwechselbare Abkürzungen, die anderweitig noch nicht ver-
wendet werden.


>>> Aber Intel hat das 64-Bit Instruction Set eben von AMD
>>> übernommen und seine eigene 64-Bit-Architektur praktisch aufgegeben.
>> Dass IA64-Prozessoren nicht mehr auf dem Consumermarkt ver-
>> trieben werden, heisst nicht, dass iNTEL diese Familie ganz
>> aufgegeben hat. Sie wird in anderen Marktsegmenten durchaus
>> noch verwendet und meines Wissens immer noch produziert.
>
> In letzter Zeit mal was von Kittson gehört?


Ja. Ich kenne durch Genealogierecherchen jemanden in Hallock,
mit dem ich kürzlich ein paar E-mails austauschte.

Bernhard Schornak

unread,
Dec 15, 2014, 9:54:45 AM12/15/14
to
Peter J. Holzer schrieb:


> Ja, ich merke es. Du hängst Dich daran auf, dass da keine ganze Zahl
> steht. Mir ist das hingegen ziemlich egal, erstens weil es ein
> Durchschnitt sein könnte, und zweitens weil Du mit fast 100%-iger
> Sicherheit die falsche Zahl zitiert hast. Ob da 1, 1.5 oder 2 Takte
> steht - es ist garantiert falsch für einen Memory-Zugriff.


Okay, noch einmal von vorne. Was ich postete war:

>> AMD : 5 Takte FP-Double statt 6/7 Takte Complex
>> iNTEL: 1.5 (???) statt 5 Takte

Bulldozer benötigt lesenderweise 4 Takte für L1-Hits. Die meisten
Schreibzugriffe werden durch Write-Combining "versteckt", so dass
sich das Schreiben auf einen Takt reduziert, die restlichen Takte
"schluckt" das Speicherinterface. Die Angaben von AMD sind durch-
aus realistisch angesetzt und daher glaubhaft. (Complex blockiert
die vier Execution Pipes des Kerns, ist also ein kostenintensiver
Befehl - man könnte in der gegebenen Zeit im günstigsten Fall bis
zu 24/28 einfache FastPath-Befehle ausführen!)

Was (nicht nur wegen der "krummen" Angaben!) nicht glaubhaft ist,
sind die Angaben von iNTEL, die aus dem

"Intel® 64 and IA-32 Architectures Optimization Reference Manual,
Order Number: 248966-020" (veröffentlicht 2009)

stammten. Im Gegensatz zu AMD informiert uns iNTEL nicht darüber,
ob sich diese Angaben auf einen Register-Register- oder einen Re-
gister-Speicher-Zugriff beziehen (AMD listet jede Zugriffsform in
einer gesonderten Zeile).

Addendum: In der neuesten 248966-Version von 2011 wird inzwischen
angegeben, dass die 1.5 Takte für XCHG einer Register-Register-Op
entsprechen. Wie der CMPXCHG-Wert zustande kommt, muss man weiter
raten, da weiterführende Angaben nach wie vor fehlen.


Generell: Taktangaben sind keine Durchschnittswerte, sondern eine
-exakt- messbare Anzahl von Taktzyklen, die zur Abarbeitung eines
Befehls benötigt werden. Die Abarbeitungszeit jedes Befehls hängt
vom Prozessordesign ab - sie kann vom Hersteller für jeden Befehl
mittels Prozessorsimulation auf den Takt genau bestimmt werden.

Da ein Taktzyklus physikalisch die -kleinste- vorkommende Einheit
ist, kann das Ergebnis eines Befehls niemals nach einem Bruchteil
eines Taktes ausgegeben werden, wie uns iNTELs Angabe suggerieren
möchte - das ist physikalisch unmöglich!

Irgendwo in c.l.a.x86 oder a.l.a gab es schon einmal eine diesbe-
zügliche Diskussion, in der es ebenfalls um halbe Taktzyklen ging
- ich kann den entsprechenden Thread leider nicht mehr finden, da
mir inzwischen der Titel entfallen ist (war 2012 oder 2013).

BTW: Für mystische Zahlenspiele dürften sich in de.alt.astrologie
oder de.alt.paranormal sicher recht interessante Gesprächspartner
finden... ;)

Steffen Christgau

unread,
Dec 15, 2014, 5:12:21 PM12/15/14
to
On 15.12.2014 15:51, Bernhard Schornak wrote:
> Volker Birk schrieb:
>> Bernhard Schornak <scho...@web.de> wrote:
>>> Peter J. Holzer schrieb:
>>>> ISA = Instruction Set Architecture […]
>>>> CPI
>>> […]
>>> Wer im Bereich Computertechnik nach den von Dir verwendeten
>>> Abkürzungen gurgelt, wird auf den ersten fünf Seiten keinen
>>> einzigen Treffer mit den von Dir nachgereichten Bedeutungen
>>> finden.
>>
>> https://en.wikipedia.org/wiki/Instruction_set
>
> In der verlinkten deutschen Version des obigen Artikels
>
> https://de.wikipedia.org/wiki/Befehlssatz
>
> wird die Abkürzung ISA nirgendwo erwähnt.

<krümelk*ck>
Stimmt so nicht.

"Will man eine Familie von Prozessoren mit ähnlichem Befehlssatz
zusammenfassen, so spricht man auch von einer Befehlssatzarchitektur
(engl. Instruction Set Architecture, kurz: ISA). Verbreitete
Befehlssatzarchitekturen sind beispielsweise:

* IA-32 (oder auch x86 genannt)"

Die Versiongeschichte zeigt die letzte Änderung am 21. August diesen
Jahres.
</krümelk*ck>

> ist nur in einer englischen Version verfügbar. Ich sollte ihn
> -möglicherweise- kennen, so lange ich in c.l.a.x86 oder a.l.a
> diskutiere, im deutschsprachigen Raum sind diesen Abkürzungen
> aber eindeutig den ursprünglichen Bedeutungen (wie von mir in
> früheren Postings bereits ausgeführt) zugeordnet.

Auch wenn die Diskussion jetzt eher off-topic wird, muss ich Peter recht
geben. Wenn hier über die Prozessorinterna geschrieben wird, ist ISA für
mich selbsterklärung - und eben nicht der betagte Bus, um den es in der
gesamten Diskussion bisher auch nicht ging. Und CPI ist meinem Empfinden
nach auch geläufig und ist im Bereich der Rechnerarchitektur/Prozessoren
eben keine Einheit für die Zeichendichte...

Just my 0,02 EUR.

Gruß, Steffen

Bernhard Schornak

unread,
Dec 16, 2014, 11:48:17 AM12/16/14
to
Steffen Christgau schrieb:


> Auch wenn die Diskussion jetzt eher off-topic wird, muss ich Peter recht
> geben. Wenn hier über die Prozessorinterna geschrieben wird, ist ISA für
> mich selbsterklärung - und eben nicht der betagte Bus, um den es in der
> gesamten Diskussion bisher auch nicht ging. Und CPI ist meinem Empfinden
> nach auch geläufig und ist im Bereich der Rechnerarchitektur/Prozessoren
> eben keine Einheit für die Zeichendichte...


Ich bin nicht gar so geizig und werfe Dir 'n ganzen Euro in'n
Hut:

Es liegt möglicherweise daran, dass unterschiedliche Menschen
unterschiedliche Interessen haben und dann die für ihr Inter-
essengebiet relevanten Publikationen lesen, die ihre eigenen,
interessenspezifischen Schlagwörter und Begriffe verwenden.

In wie weit diese "Insidersprache" sich dann im -allgemeinen-
Sprachgebrauch niederschlägt, hängt sicher davon ab, wie weit
sich ein spezifischer "Hype" unter die Leute bringen lässt.

Ich beschäftige mich hauptsächlich mit Funktionsbibliotheken,
die von den Befehlssätzen aktueller [x86-64]-Prozessoren rege
Gebrauch machen. Ich habe Begriffe wie "iNTEL-Architecture 32
(und 64) Bit" und "AMD-64" in meinen Sprachschatz aufgenommen
und kenne zumindest die fünf AMD-Handbücher für den Bulldozer
so gut, dass ich weiss, wo ich nachschlagen muss, um gesuchte
Informationen zu finden. Über ISA oder CPI bin ich aber weder
in den Publikationen von AMD noch von iNTEL gestossen - wobei
ich unterstelle, dass diese beiden Prozessorschmieden eigent-
lich die ersten sein müssten, die derlei Dinge publizieren...

Addendum:

Ich habe meine gesammelten Datenbücher gerade nach ISA durch-
sucht. Ausser in mISAligned und Ähnlichem ist diese Abkürzung
als eigenständiger Begriff nur im Zusammmenhang mit SIMD (all
das, was mit XMM/YMM/ZMM-Registern arbeitet) in Gebrauch. Für
den ursprünglichen Befehlssatz wird durchgehend IA32, x86 und
AMD64 verwendet, nur die "Legacy SIMD ISA" macht da eine Aus-
nahme...

Steffen Christgau

unread,
Dec 17, 2014, 3:26:03 PM12/17/14
to
On 16.12.2014 17:48, Bernhard Schornak wrote:
> Es liegt möglicherweise daran, dass unterschiedliche Menschen
> unterschiedliche Interessen haben und dann die für ihr Inter-
> essengebiet relevanten Publikationen lesen, die ihre eigenen,
> interessenspezifischen Schlagwörter und Begriffe verwenden.

Grundsätzlich geb ich dir recht, dass die verwendete Literatur natürlich
Einfluss auf den Sprachgebrauch hat. Vielleicht sind die
prozessorspezifischen Handbücher hier aber etwas zuuu
architektur/prozessorspezifisch als dass die beiden Begriffe darin öfter
auftauchen (müssten). Aber auch dort finden sich sowohl ISA (Software
Optimization Guide for AMD Family 15h
Processors, S. 38) als auch CPI (Intel 64 and IA-32 Architectures
Optimization Reference Manual, Abschnitt B.6.1). Ja, ich gebe zu, beides
nicht sehr oft, aber es gibt diese Begriffe - nicht nur in den Handbüchern.

Wenn man über die allgemeinere Sicht, die Grundlagen der
Rechnerarchitektur, einsteigt (was angesichts der Komplexität moderner
CPUs durchaus Sinn macht) oder sie sich später aneignet, wird man
schnell mit den genannten Begriffen (u.a.) konfrontiert. Im
Hennessy/Patterson: "Computer Architecture: A Quantitative Approach"
(IMO das Standardwerk auf dem Bereich der Rechnerarchitektur) kommen die
ziemlich weit vorne....

> In wie weit diese "Insidersprache" sich dann im -allgemeinen-
> Sprachgebrauch niederschlägt, hängt sicher davon ab, wie weit
> sich ein spezifischer "Hype" unter die Leute bringen lässt.

... von daher würde nicht von Hype sprechen. Und Insidersprache
verwenden wir hier auf unserer Assemblerinsel sowieso. Die einen mehr,
die anderen weniger ;-)

Steffen

Bernhard Schornak

unread,
Dec 17, 2014, 6:07:24 PM12/17/14
to
Steffen Christgau schrieb:


> On 16.12.2014 17:48, Bernhard Schornak wrote:
>> Es liegt möglicherweise daran, dass unterschiedliche Menschen
>> unterschiedliche Interessen haben und dann die für ihr Inter-
>> essengebiet relevanten Publikationen lesen, die ihre eigenen,
>> interessenspezifischen Schlagwörter und Begriffe verwenden.
>
> Grundsätzlich geb ich dir recht, dass die verwendete Literatur natürlich
> Einfluss auf den Sprachgebrauch hat. Vielleicht sind die
> prozessorspezifischen Handbücher hier aber etwas zuuu
> architektur/prozessorspezifisch als dass die beiden Begriffe darin öfter
> auftauchen (müssten). Aber auch dort finden sich sowohl ISA (Software
> Optimization Guide for AMD Family 15h
> Processors, S. 38) als auch CPI (Intel 64 and IA-32 Architectures
> Optimization Reference Manual, Abschnitt B.6.1). Ja, ich gebe zu, beides
> nicht sehr oft, aber es gibt diese Begriffe - nicht nur in den Handbüchern.


Welche Ausgabe des AMD 47414 war das? In der aktuellen Version
3.08 vom Januar 2014 sehe ich alle möglichen Kürzel, aber kein
ISA http://tinyurl.com/lfmlywm - auch auf den Seiten davor und
danach nicht.

Intel spricht von Clocks Per Instructions Retired Ratio (CPI),
was nicht mit Befehlen pro Takt gleichzusetzen ist. Es ist ein
angenommenes Verhältnis, kein gemessener Wert.

Insgesamt sind mir AMDs Angaben sympathischer, da es reale (d.
h. nachmessbare) Werte sind.


> Wenn man über die allgemeinere Sicht, die Grundlagen der
> Rechnerarchitektur, einsteigt (was angesichts der Komplexität moderner
> CPUs durchaus Sinn macht) oder sie sich später aneignet, wird man
> schnell mit den genannten Begriffen (u.a.) konfrontiert. Im
> Hennessy/Patterson: "Computer Architecture: A Quantitative Approach"
> (IMO das Standardwerk auf dem Bereich der Rechnerarchitektur) kommen die
> ziemlich weit vorne....


Das ist sicher ein (bekanntes?) Werk, das man beim Informatik-
studium zu lesen hat. Als Autodidakt baue ich eher auf eine in
mehr als dreissig Jahren erarbeitete Praxis mit Computern auf.
Die Spezialisierung auf x86 begann 1993, die auf x86-64 2009 -
nicht allzu lange her, aber ausreichend, damit warm zu werden.


>> In wie weit diese "Insidersprache" sich dann im -allgemeinen-
>> Sprachgebrauch niederschlägt, hängt sicher davon ab, wie weit
>> sich ein spezifischer "Hype" unter die Leute bringen lässt.
>
> ... von daher würde nicht von Hype sprechen. Und Insidersprache
> verwenden wir hier auf unserer Assemblerinsel sowieso. Die einen mehr,
> die anderen weniger ;-)


In der Programmierung herrscht die englische Sprache vor - das
zu Leugnen wäre Blödsinn. Trotzdem versuche ich (im Rahmen der
Möglichkeiten) deutsche Begriffe zu verwenden, um das, was ich
zu sagen habe, einem möglichst breiten "Publikum" verständlich
zu machen. Ich schreibe zwar fast ebenso gut in englischer wie
in deutscher Sprache, empfände es aber als unhöflich, in einer
deuschsprachigen NG mit Anglizismen um mich zu werfen. Wenn es
sich gar nicht vermeiden lässt, schreibe ich demnach immer ein
paar erklärende Worte zu den Fachbegriffen, von denen ich ver-
mute, dass sie nicht jeder wissen muss.

Jan Bruns

unread,
Dec 17, 2014, 11:21:02 PM12/17/14
to

Bernhard Schornak:
> Peter J. Holzer schrieb:

>> 1.5 Takte, wenn mit einer anderen CPU kommuniziert werden muss? Die
>> Zeitangabe bezieht sich wohl auf ein XCHG von zwei Registern im selben
>> Core, aber ganz sicher nicht auf einen Speicherzugriff.
>
>
> Oder auf neuartige Logikgatter, die bei steigenden und fallenden Flanken
> des Taktsignals schalten.

Logikgatter schalten für gewöhnlich bei beliebigen Änderungen an
den Eingängen, völlig unabhängig von irgendwelchen Takten.

Deshalb nennt man allein aus Logikbausteinen aufgebaute Schaltungen
auch "rein kombinatorisch".

Taktsignale werden verwendet, um für Speicherelemente (FlipFlops)
ein Zeitfenster zu schaffen, in dem sie von ihrer eigentlichen
SpeicherfFunktion abweichend mit neuen Werten geladen werden können.

Dabei spricht (soweit ich weiss) prinzipiell rein gar nichts
dagegen, diese Zeitfenster an beiden Flanken eines Taktsignals
auszurichten.

Wenn man das erreichen will, jedoch aus irgendwelchen Gründen nur
auf Einzelflanken reagierende Speicherlemente verwenden kann (z.B.
weil das einfach eine so selten benötigte Funktionalität ist, daß
das DDR-Teil nicht in der Bauteilbibliothek verfügbar ist), dann
kann man so ein DDR-FlipFlop aufbauen, indem man zwei der verfüg-
baren Speicherelemente verwendet, und entsprechend beschaltet (in
die nachfolgende kombinatorische Schaltung absorbiert).

Gruss

Jan Bruns








Bernhard Schornak

unread,
Dec 18, 2014, 11:19:50 AM12/18/14
to
Jan Bruns schrieb:


> Bernhard Schornak:
>> Peter J. Holzer schrieb:
>
>>> 1.5 Takte, wenn mit einer anderen CPU kommuniziert werden muss? Die
>>> Zeitangabe bezieht sich wohl auf ein XCHG von zwei Registern im selben
>>> Core, aber ganz sicher nicht auf einen Speicherzugriff.
>>
>>
>> Oder auf neuartige Logikgatter, die bei steigenden und fallenden Flanken
>> des Taktsignals schalten.
>
> Logikgatter schalten für gewöhnlich bei beliebigen Änderungen an
> den Eingängen, völlig unabhängig von irgendwelchen Takten.


Richtig. Wieviele Prozessoren bestehen ausschliesslich aus
Invertern, AND-, NAND-, OR-, NOR- und XOR-Gattern, die un-
abhängig von einem Takt arbeiten? Welcher Speicherbaustein
auf einem IC funktioniert ohne Takt? Wenn ich mich richtig
erinnere, benötigten auch die analogen Eimerkettenspeicher
einen Takt, mit dem die Kondensatorladungen weitergereicht
werden mussten, da sie sonst verloren gingen.


> Deshalb nennt man allein aus Logikbausteinen aufgebaute Schaltungen
> auch "rein kombinatorisch".


http://tinyurl.com/qd27ql7


> Taktsignale werden verwendet, um für Speicherelemente (FlipFlops)
> ein Zeitfenster zu schaffen, in dem sie von ihrer eigentlichen
> SpeicherfFunktion abweichend mit neuen Werten geladen werden können.
>
> Dabei spricht (soweit ich weiss) prinzipiell rein gar nichts
> dagegen, diese Zeitfenster an beiden Flanken eines Taktsignals
> auszurichten.


http://tinyurl.com/p4ynptr
(=> zweiflankengesteuerte Flipflops)


> Wenn man das erreichen will, jedoch aus irgendwelchen Gründen nur
> auf Einzelflanken reagierende Speicherlemente verwenden kann (z.B.
> weil das einfach eine so selten benötigte Funktionalität ist, daß
> das DDR-Teil nicht in der Bauteilbibliothek verfügbar ist), dann
> kann man so ein DDR-FlipFlop aufbauen, indem man zwei der verfüg-
> baren Speicherelemente verwendet, und entsprechend beschaltet (in
> die nachfolgende kombinatorische Schaltung absorbiert).


http://tinyurl.com/komp56x

Das scheint 1. noch nicht ganz augereift und 2. noch nicht
besonders schnell (100 - 400 MHz) zu sein. Wie die Ausgabe
von zwei Ergebnissen pro Taktzyklus funktioniert, wenn nur
je ein Ausgang und ein Eingang der nächsten Stufe der Pipe
zur Verfügung stehen, wäre damit allerdings nicht geklärt.
Welche aktuellen Desktop-Prozessoren verwenden diese Tech-
nologie tatsächlich?

Steffen Christgau

unread,
Dec 18, 2014, 3:37:13 PM12/18/14
to
On 18.12.2014 00:07, Bernhard Schornak wrote:
> Steffen Christgau schrieb:
>> On 16.12.2014 17:48, Bernhard Schornak wrote:
>>> Es liegt möglicherweise daran, dass unterschiedliche Menschen
>>> unterschiedliche Interessen haben und dann die für ihr Inter-
>>> essengebiet relevanten Publikationen lesen, die ihre eigenen,
>>> interessenspezifischen Schlagwörter und Begriffe verwenden.
>>
>> Grundsätzlich geb ich dir recht, dass die verwendete Literatur natürlich
>> Einfluss auf den Sprachgebrauch hat. Vielleicht sind die
>> prozessorspezifischen Handbücher hier aber etwas zuuu
>> architektur/prozessorspezifisch als dass die beiden Begriffe darin öfter
>> auftauchen (müssten). Aber auch dort finden sich sowohl ISA (Software
>> Optimization Guide for AMD Family 15h
>> Processors, S. 38) als auch CPI (Intel 64 and IA-32 Architectures
>> Optimization Reference Manual, Abschnitt B.6.1). Ja, ich gebe zu, beides
>> nicht sehr oft, aber es gibt diese Begriffe - nicht nur in den
>> Handbüchern.
>
>
> Welche Ausgabe des AMD 47414 war das? In der aktuellen Version
> 3.08 vom Januar 2014 sehe ich alle möglichen Kürzel, aber kein
> ISA http://tinyurl.com/lfmlywm - auch auf den Seiten davor und
> danach nicht.

Ah, sorry. Ich war noch bei 3.06.

In der 3.08 ist es aber auch drin, eine Seite später (S. 39, ziemlich
weit unten); http://support.amd.com/TechDocs/47414_15h_sw_opt_guide.pdf

> Intel spricht von Clocks Per Instructions Retired Ratio (CPI),
> was nicht mit Befehlen pro Takt gleichzusetzen ist.

"Befehle pro Takt" sind "Instructions per Cycle", oder kurz IPC. Klar
ist das nicht gleichzusetzen mit "Clocks [oder Cycles] per Instructions"
bzw. CPI. Hab ich auch nicht getan. Das eine ist das Reziproke vom
anderen. Mir gehts hier nur um die vermeintlich unbekannten
Begrifflichkeiten bzw. Abkürzungen.

> Es [CPI] ist ein angenommenes Verhältnis, kein gemessener Wert.

Mh, aber Intel beschreibt doch in dem angegebenen Werk an der
angegebenen Stelle (s.o), wie CPI zu messen sind: Mit Hilfe von zwei
Hardware-Countern. Da sehe ich ehrlich gesagt nicht, wie das ein
"angenommenes Verhältnis" sein kann.

>> Wenn man über die allgemeinere Sicht, die Grundlagen der
>> Rechnerarchitektur, einsteigt (was angesichts der Komplexität moderner
>> CPUs durchaus Sinn macht) oder sie sich später aneignet, wird man
>> schnell mit den genannten Begriffen (u.a.) konfrontiert. Im
>> Hennessy/Patterson: "Computer Architecture: A Quantitative Approach"
>> (IMO das Standardwerk auf dem Bereich der Rechnerarchitektur) kommen die
>> ziemlich weit vorne....
>
> Das ist sicher ein (bekanntes?) Werk, das man beim Informatik-
> studium zu lesen hat.

Ja, ist es. Wenn man im Studium was zur Rechnerarchitektur gehört, dann
wird man mit großer Wahrscheinlichkeit auch von oder aus diesem Buch
gehört haben...

> Als Autodidakt baue ich eher auf eine in
> mehr als dreissig Jahren erarbeitete Praxis mit Computern auf.
> Die Spezialisierung auf x86 begann 1993, die auf x86-64 2009 -
> nicht allzu lange her, aber ausreichend, damit warm zu werden.

Sicher. Will ich dir auch nichts absprechen. Aber CPI und ISA als
unbekannte (oder unübliche) Begriffe darzustellen, wollte ich so nicht
stehen lassen.

Gruß, Steffen

Bernhard Schornak

unread,
Dec 19, 2014, 10:32:20 AM12/19/14
to
Steffen Christgau schrieb:


> On 18.12.2014 00:07, Bernhard Schornak wrote:
>> Steffen Christgau schrieb:
>>> On 16.12.2014 17:48, Bernhard Schornak wrote:
>>>> Es liegt möglicherweise daran, dass unterschiedliche Menschen
>>>> unterschiedliche Interessen haben und dann die für ihr Inter-
>>>> essengebiet relevanten Publikationen lesen, die ihre eigenen,
>>>> interessenspezifischen Schlagwörter und Begriffe verwenden.
>>>
>>> Grundsätzlich geb ich dir recht, dass die verwendete Literatur natürlich
>>> Einfluss auf den Sprachgebrauch hat. Vielleicht sind die
>>> prozessorspezifischen Handbücher hier aber etwas zuuu
>>> architektur/prozessorspezifisch als dass die beiden Begriffe darin öfter
>>> auftauchen (müssten). Aber auch dort finden sich sowohl ISA (Software
>>> Optimization Guide for AMD Family 15h
>>> Processors, S. 38) als auch CPI (Intel 64 and IA-32 Architectures
>>> Optimization Reference Manual, Abschnitt B.6.1). Ja, ich gebe zu, beides
>>> nicht sehr oft, aber es gibt diese Begriffe - nicht nur in den
>>> Handbüchern.
>>
>> Welche Ausgabe des AMD 47414 war das? In der aktuellen Version
>> 3.08 vom Januar 2014 sehe ich alle möglichen Kürzel, aber kein
>> ISA http://tinyurl.com/lfmlywm - auch auf den Seiten davor und
>> danach nicht.
>
> Ah, sorry. Ich war noch bei 3.06.
>
> In der 3.08 ist es aber auch drin, eine Seite später (S. 39, ziemlich
> weit unten); http://support.amd.com/TechDocs/47414_15h_sw_opt_guide.pdf


Der Absatz ganz unten bezieht sich (wie bei iNTEL) auf 128 und
256 Bit breite "Media Register" (XMM/YMM). Das Bulldozerdesign
fass ja die beiden 128 Bit breiten FPUs der beiden Kerne einer
Einheit/Unit bei AVX-Befehlen zu einer 256 Bit breiten Einheit
zusammen, weshalb in Taktzyklen mit AVX-Befehlen nur einer der
beiden Kerne über die FPU verfügen kann. Dieses "Nadelöhr" ist
neben dem gemeinsamen Befehlsdekoder wohl die grösste Schwach-
stelle des Bulldozerdesigns...


>> Intel spricht von Clocks Per Instructions Retired Ratio (CPI),
>> was nicht mit Befehlen pro Takt gleichzusetzen ist.
>
> "Befehle pro Takt" sind "Instructions per Cycle", oder kurz IPC. Klar
> ist das nicht gleichzusetzen mit "Clocks [oder Cycles] per Instructions"
> bzw. CPI. Hab ich auch nicht getan. Das eine ist das Reziproke vom
> anderen. Mir gehts hier nur um die vermeintlich unbekannten
> Begrifflichkeiten bzw. Abkürzungen.


Es ist nicht das Reziproke: "Cycles Per Instruction" (CPI) be-
ziehen sich auf eine einzelne Executionpipe, "Instructions per
Cycle" auf die Gesamtheit der Executionpipes (Integer + FP) in
einem einzelnen Kern. Das eine ist auch als "Latenz"(zeit) be-
kannt, da andere als "(maximaler) Befehlsdurchsatz".

Wichtig ist in unserem Disput ja nur, dass Intel die Abkürzung
CPI für "Clocks Per Instructions Retired Ratio", nicht "Clocks
per Instruction" verwendet. Die Mehrzahl "Instructions" ergibt
im Englischen nur in Zusammenhang mit Retired einen Sinn - an-
sonsten wäre das "Clocks Per Instructions" nicht viel mehr als
extrem schlechtes, mit Valentins Semmelnknödeln vergleichbares
Englisch.


>> Es [CPI] ist ein angenommenes Verhältnis, kein gemessener Wert.
>
> Mh, aber Intel beschreibt doch in dem angegebenen Werk an der
> angegebenen Stelle (s.o), wie CPI zu messen sind: Mit Hilfe von zwei
> Hardware-Countern. Da sehe ich ehrlich gesagt nicht, wie das ein
> "angenommenes Verhältnis" sein kann.


B-51, unten:

"1. Clocks Per Instruction Retired Ratio (CPI):
CPU_CLK_UNHALTED.CORE / INST_RETIRED.ANY.

The Intel Core microarchitecture is capable of reaching CPI
as low as 0.25 in ideal situations. But most of the code has
higher CPI The greater value of CPI for a given workload
indicate it has more opportunity for code tuning to improve
performance. The CPI is an overall metric, it does not
provide specificity of what microarchitectural sub-system
may be contributing to a high CPI value."

Wenn man die beiden Seiten liest, sollte einem eigentlich klar
sein, dass die angegebenen Formeln nur für grobe "Schätzungen"
taugen. Messen kann man keines der auf B-51/B-52 aufgelisteten
Verhältnisse. Wie willst Du z.B. RESOURCE_STALLS.RS_FULL genau
bestimmen, um es dann in die Formel einsetzen zu können? iNTEL
kann den Wert in einem Kern-Simulator wohl bestimmen, dem ein-
fachen Anwendungsprogrammierer steht diese Möglichkeit nun mal
nicht zur Verfügung. (Ob man eigens dafür angelegten MSRs über
den Weg trauen kann, sei dahingestellt.)


>>> Wenn man über die allgemeinere Sicht, die Grundlagen der
>>> Rechnerarchitektur, einsteigt (was angesichts der Komplexität moderner
>>> CPUs durchaus Sinn macht) oder sie sich später aneignet, wird man
>>> schnell mit den genannten Begriffen (u.a.) konfrontiert. Im
>>> Hennessy/Patterson: "Computer Architecture: A Quantitative Approach"
>>> (IMO das Standardwerk auf dem Bereich der Rechnerarchitektur) kommen die
>>> ziemlich weit vorne....
>>
>> Das ist sicher ein (bekanntes?) Werk, das man beim Informatik-
>> studium zu lesen hat.
>
> Ja, ist es. Wenn man im Studium was zur Rechnerarchitektur gehört, dann
> wird man mit großer Wahrscheinlichkeit auch von oder aus diesem Buch
> gehört haben...


Okay - ich bin auf x86-64 spezialisiert, daher beschäftige ich
mich nur rudimentär (und dann nur mit offen zugänglichen Doku-
menten) über andere Prozessordesigns. Als Hobby-Programmierer/
-Elektroniker muss ich auch nicht alles auswendig wissen...


>> Als Autodidakt baue ich eher auf eine in
>> mehr als dreissig Jahren erarbeitete Praxis mit Computern auf.
>> Die Spezialisierung auf x86 begann 1993, die auf x86-64 2009 -
>> nicht allzu lange her, aber ausreichend, damit warm zu werden.
>
> Sicher. Will ich dir auch nichts absprechen. Aber CPI und ISA als
> unbekannte (oder unübliche) Begriffe darzustellen, wollte ich so nicht
> stehen lassen.


Ich beharre nicht aus purer Sturheit auf Diesem und Jenem, und
bin mit guten Argumenten jederzeit zu überzeugen. Bei mehrfach
belegten Begriffen ist letzteres ein wenig schwieriger als bei
Allerweltsbegriffen. ;)


Schönes Wochenende!

Bernhard Schornak

Peter J. Holzer

unread,
Dec 20, 2014, 8:39:52 AM12/20/14
to
On 2014-12-15 14:55, Bernhard Schornak <scho...@web.de> wrote:
> "Intel® 64 and IA-32 Architectures Optimization Reference Manual,
> Order Number: 248966-020" (veröffentlicht 2009)

Ah, eine Quellenangabe. Danke.


> stammten. Im Gegensatz zu AMD informiert uns iNTEL nicht darüber,
> ob sich diese Angaben auf einen Register-Register- oder einen Re-
> gister-Speicher-Zugriff beziehen (AMD listet jede Zugriffsform in
> einer gesonderten Zeile).
>
> Addendum: In der neuesten 248966-Version von 2011 wird inzwischen
> angegeben, dass die 1.5 Takte für XCHG einer Register-Register-Op
> entsprechen. Wie der CMPXCHG-Wert zustande kommt, muss man weiter
> raten, da weiterführende Angaben nach wie vor fehlen.

In der allerneuesten (248966-30, September 2014) steht auch das drin.
(Soweit ich sehe, stehen dort nur Befehle mit Register- und
Immediate-Operanden. Die mit Memory-Operanden haben sie sich wohl
wegen der Abhängigkeit von externen Faktoren gespart.)

> Generell: Taktangaben sind keine Durchschnittswerte, sondern eine
> -exakt- messbare Anzahl von Taktzyklen, die zur Abarbeitung eines
> Befehls benötigt werden.

Die aber nicht konstant ist. Hängt teilweise von den Operanden ab (z.B.
bei DIV) und bei superskalaren out-of-order Architekturen natürlich auch
davon, was da sonst so in der Pipeline hängt.

> Die Abarbeitungszeit jedes Befehls hängt
> vom Prozessordesign ab - sie kann vom Hersteller für jeden Befehl
> mittels Prozessorsimulation auf den Takt genau bestimmt werden.
>
> Da ein Taktzyklus physikalisch die -kleinste- vorkommende Einheit
> ist, kann das Ergebnis eines Befehls niemals nach einem Bruchteil
> eines Taktes ausgegeben werden, wie uns iNTELs Angabe suggerieren
> möchte - das ist physikalisch unmöglich!

In 248966-30, Kapitel 15.4 gibt es eine Spalte "Throughput" und eine
Spalte "Latency". Die "krummen" Taktzahlen kommen ausschließlich in der
Spalte Throughput vor. Darüber steht die Erklärung:

| Throughput value listed as “n/m”, where ‘m’ ops can be dispatched
| every ‘n’ cycle.

Wenn dort also 0.5 steht, dann heißt das, dass der Prozessor 2 dieser
Instruktionen pro Zyklus absetzen kann (oder 4 alle 2 Takte, 6 alle 3
Takte, ...). 1.5 (was in der Silvermont-Architektur nicht vorkommt)
hieße dann wohl 2 parallele Instruktionen alle 3 Takte.

(Also genau das, was ich vermutet hatte)

> Irgendwo in c.l.a.x86 oder a.l.a gab es schon einmal eine diesbe-
> zügliche Diskussion, in der es ebenfalls um halbe Taktzyklen ging
> - ich kann den entsprechenden Thread leider nicht mehr finden, da
> mir inzwischen der Titel entfallen ist (war 2012 oder 2013).
>
> BTW: Für mystische Zahlenspiele dürften sich in de.alt.astrologie
> oder de.alt.paranormal sicher recht interessante Gesprächspartner
> finden... ;)

Das hat nichts mit Mystik zu tun. Man muss nur lesen und dabei das Hirn
einschalten, Natürlich hilft es beim Lesen, wenn man davon ausgeht, dass
sich die Autoren des Handbuchs etwas dabei gedacht haben und nicht mit
der Einstellung "Intel-Mitarbeiter sind alle Volltrottel" herangeht.

Peter J. Holzer

unread,
Dec 20, 2014, 8:59:00 AM12/20/14
to
On 2014-12-19 15:32, Bernhard Schornak <scho...@web.de> wrote:
> Wenn man die beiden Seiten liest, sollte einem eigentlich klar
> sein, dass die angegebenen Formeln nur für grobe "Schätzungen"
> taugen. Messen kann man keines der auf B-51/B-52 aufgelisteten
> Verhältnisse. Wie willst Du z.B. RESOURCE_STALLS.RS_FULL genau
> bestimmen, um es dann in die Formel einsetzen zu können?

Das ist ein Counter in der CPU, den kannst Du mit

RDPMC—Read Performance-Monitoring Counters

auslesen.

Bernhard Schornak

unread,
Dec 20, 2014, 1:00:27 PM12/20/14
to
Peter J. Holzer schrieb:


> On 2014-12-19 15:32, Bernhard Schornak <scho...@web.de> wrote:
>> Wenn man die beiden Seiten liest, sollte einem eigentlich klar
>> sein, dass die angegebenen Formeln nur für grobe "Schätzungen"
>> taugen. Messen kann man keines der auf B-51/B-52 aufgelisteten
>> Verhältnisse. Wie willst Du z.B. RESOURCE_STALLS.RS_FULL genau
>> bestimmen, um es dann in die Formel einsetzen zu können?
>
> Das ist ein Counter in der CPU, den kannst Du mit
>
> RDPMC—Read Performance-Monitoring Counters
>
> auslesen.


Danke!


Schönes Wochenende

Bernhard Schornak

Bernhard Schornak

unread,
Dec 20, 2014, 1:02:32 PM12/20/14
to
Peter J. Holzer schrieb:


> On 2014-12-15 14:55, Bernhard Schornak <scho...@web.de> wrote:
>> "Intel® 64 and IA-32 Architectures Optimization Reference Manual,
>> Order Number: 248966-020" (veröffentlicht 2009)
>
> Ah, eine Quellenangabe. Danke.
>
>> stammten. Im Gegensatz zu AMD informiert uns iNTEL nicht darüber,
>> ob sich diese Angaben auf einen Register-Register- oder einen Re-
>> gister-Speicher-Zugriff beziehen (AMD listet jede Zugriffsform in
>> einer gesonderten Zeile).
>>
>> Addendum: In der neuesten 248966-Version von 2011 wird inzwischen
>> angegeben, dass die 1.5 Takte für XCHG einer Register-Register-Op
>> entsprechen. Wie der CMPXCHG-Wert zustande kommt, muss man weiter
>> raten, da weiterführende Angaben nach wie vor fehlen.
>
> In der allerneuesten (248966-30, September 2014) steht auch das drin.


Ja. Das 2011 war aus einem anderen iNTEL-Handbuch, da habe ich
wohl etwas durcheinander gebracht.


>> Generell: Taktangaben sind keine Durchschnittswerte, sondern eine
>> -exakt- messbare Anzahl von Taktzyklen, die zur Abarbeitung eines
>> Befehls benötigt werden.
>
> Die aber nicht konstant ist. Hängt teilweise von den Operanden ab (z.B.
> bei DIV) und bei superskalaren out-of-order Architekturen natürlich auch
> davon, was da sonst so in der Pipeline hängt.


AMD gibt für DIV eine Formel zur Berechnung der tatsächlich zu
veranschlagenden Latenz an. Bei iNTEL sucht man derlei Angaben
vergeblich. Möglicherweise sind sie ja nur sehr gut versteckt,
und man findet sie auf einer nirgendwo angegebenen Seite...


>> Die Abarbeitungszeit jedes Befehls hängt
>> vom Prozessordesign ab - sie kann vom Hersteller für jeden Befehl
>> mittels Prozessorsimulation auf den Takt genau bestimmt werden.
>>
>> Da ein Taktzyklus physikalisch die -kleinste- vorkommende Einheit
>> ist, kann das Ergebnis eines Befehls niemals nach einem Bruchteil
>> eines Taktes ausgegeben werden, wie uns iNTELs Angabe suggerieren
>> möchte - das ist physikalisch unmöglich!
>
> In 248966-30, Kapitel 15.4 gibt es eine Spalte "Throughput" und eine
> Spalte "Latency". Die "krummen" Taktzahlen kommen ausschließlich in der
> Spalte Throughput vor. Darüber steht die Erklärung:
>
> | Throughput value listed as “n/m”, where ‘m’ ops can be dispatched
> | every ‘n’ cycle.
>
> Wenn dort also 0.5 steht, dann heißt das, dass der Prozessor 2 dieser
> Instruktionen pro Zyklus absetzen kann (oder 4 alle 2 Takte, 6 alle 3
> Takte, ...). 1.5 (was in der Silvermont-Architektur nicht vorkommt)
> hieße dann wohl 2 parallele Instruktionen alle 3 Takte.


"Der Prozessor" könnte mit Sicherheit auch 2*n solcher Befehle
pro Takt abarbeiten, wenn seine n Kernen zufällig simultan den
selben Befehl ausführen. Unsere Diskussion bezog sich aber auf
eine einzige Executionpipe eines einzigen Kerns, nicht auf die
Gesamtheit aller Kerne/Prozessoren eines komplexen Systems. Es
ist also müssig, plötzlich den ganzen Kern zu bemühen, da eine
einzelne Executionpipe den angegebenen Durchsatz nicht bringen
kann.


> (Also genau das, was ich vermutet hatte)


Ditto.


>> BTW: Für mystische Zahlenspiele dürften sich in de.alt.astrologie
>> oder de.alt.paranormal sicher recht interessante Gesprächspartner
>> finden... ;)
>
> Das hat nichts mit Mystik zu tun. Man muss nur lesen und dabei das Hirn
> einschalten, Natürlich hilft es beim Lesen, wenn man davon ausgeht, dass
> sich die Autoren des Handbuchs etwas dabei gedacht haben und nicht mit
> der Einstellung "Intel-Mitarbeiter sind alle Volltrottel" herangeht.


Für mich war dieses (von Dir ja geschickt herausgeschnippte)
Zitat Deines vorhergehenden Beitrags


>> Damit bleibt mir nur noch "386" zu sagen, und damit meine
>> ich auch nicht den Intel-Prozessor.


ein Musterbeispiel für Zahlenmystik. Die - ganz nebenbei be-
merkt - weder mit Handbücher schreibenden iNTEL-Mitarbeitern
noch mit mir etwas zu tun hat. Als CB-Funker sind mir sicher
die üblichen Zahlenkürzel aus der Funkersprache bekannt, die
sind aber ebenso aus einem - dem Rest der Welt unbekannten -
Fachjargon entnommen wie Dein "386". Ich könnte jetzt ja mal
wild zu spekulieren anfangen und Dein 386 (analog zu den von
Neonazis verwendeten Zahlenspielereien) zu CHF umdeuten. Das
lasse ich aber tunlichst bleiben, da es 1. unerquicklich ist
und 2. wertvolle Zeit vergeudet.


Schönes Wochenende

Bernhard Schornak

Peter J. Holzer

unread,
Dec 20, 2014, 5:30:05 PM12/20/14
to
On 2014-12-20 18:03, Bernhard Schornak <scho...@web.de> wrote:
> Peter J. Holzer schrieb:
>> On 2014-12-15 14:55, Bernhard Schornak <scho...@web.de> wrote:
>>> Die Abarbeitungszeit jedes Befehls hängt vom Prozessordesign ab -
>>> sie kann vom Hersteller für jeden Befehl mittels Prozessorsimulation
>>> auf den Takt genau bestimmt werden.
>>>
>>> Da ein Taktzyklus physikalisch die -kleinste- vorkommende Einheit
>>> ist, kann das Ergebnis eines Befehls niemals nach einem Bruchteil
>>> eines Taktes ausgegeben werden, wie uns iNTELs Angabe suggerieren
>>> möchte - das ist physikalisch unmöglich!
>>
>> In 248966-30, Kapitel 15.4 gibt es eine Spalte "Throughput" und eine
>> Spalte "Latency". Die "krummen" Taktzahlen kommen ausschließlich in der
>> Spalte Throughput vor. Darüber steht die Erklärung:
>>
>> | Throughput value listed as “n/m”, where ‘m’ ops can be dispatched
>> | every ‘n’ cycle.
>>
>> Wenn dort also 0.5 steht, dann heißt das, dass der Prozessor 2 dieser
>> Instruktionen pro Zyklus absetzen kann (oder 4 alle 2 Takte, 6 alle 3
>> Takte, ...). 1.5 (was in der Silvermont-Architektur nicht vorkommt)
>> hieße dann wohl 2 parallele Instruktionen alle 3 Takte.
>
>
> "Der Prozessor" könnte mit Sicherheit auch 2*n solcher Befehle
> pro Takt abarbeiten, wenn seine n Kernen zufällig simultan den
> selben Befehl ausführen. Unsere Diskussion bezog sich aber auf
> eine einzige Executionpipe eines einzigen Kerns, nicht auf die
> Gesamtheit aller Kerne/Prozessoren eines komplexen Systems.

Ach deswegen erwähnst Du dauernd "mehrere Pipelines". Etwas gewundert
hat mich das schon, aber ich dachte, Du stellst Dir eine superskalare
Architektur so vor, dass da ein Kern mehrere Pipelines hat, die er
parallel abarbeitet.

Nein, wir reden von einem Kern mit einer Pipeline. In jedem Takt liest
der Kern (bis zu) 4 Instruktionen und schiebt die in die Pipeline. Die
werden dann dekodiert und in jedem Takt können (bis zu) 8
Mikroinstruktionen weitergereicht werden. Die werden dann abgearbeitet,
wobei manches parallel geht (zwei Additionen z.B.) manches umsortiert
werden kann (z.B. können "spätere" Register-Operationen vorgezogen
werden, während eine Lese-Operation auf das Memory wartet), manches
spekulativ ausgeführt wird (Operationen hinter einem bedingten Sprung)
und manches muss halt seriell ausgeführt werden.

Und ja, das heißt, dass ein Kern zwei der Instruktionen, bei denen im
Manual 0.5 steht, im gleichen Takt abarbeiten kann (und noch zwei
andere). Generell kann man diese Zahlen (weder Throughput noch Latency)
nicht einfach addieren, um herauszufinden, wie lange eine
Instruktionssequenz dauert, weil da eben viel parallel abgearbeitet
wird.

(Bei Hyperthreading wird es noch ein bisschen komplizierter, aber das
können wir ignorieren)

> Es ist also müssig, plötzlich den ganzen Kern zu bemühen, da eine
> einzelne Executionpipe den angegebenen Durchsatz nicht bringen kann.

Mir ist unklar, was Du hier mit "ganzem Kern" meinst.


>> (Also genau das, was ich vermutet hatte)
>
> Ditto.

Sehr seltsam.


>>> BTW: Für mystische Zahlenspiele dürften sich in de.alt.astrologie
>>> oder de.alt.paranormal sicher recht interessante Gesprächspartner
>>> finden... ;)
>>
>> Das hat nichts mit Mystik zu tun. Man muss nur lesen und dabei das Hirn
>> einschalten, Natürlich hilft es beim Lesen, wenn man davon ausgeht, dass
>> sich die Autoren des Handbuchs etwas dabei gedacht haben und nicht mit
>> der Einstellung "Intel-Mitarbeiter sind alle Volltrottel" herangeht.
>
>
> Für mich war dieses (von Dir ja geschickt herausgeschnippte)
> Zitat Deines vorhergehenden Beitrags
>
>
>>> Damit bleibt mir nur noch "386" zu sagen, und damit meine
>>> ich auch nicht den Intel-Prozessor.
>
>
> ein Musterbeispiel für Zahlenmystik.

Du verstehst offensichtlich unter Zahlenmystik etwas anderes als ich.

Aber darauf hatte ich Deine Anmerkung nicht bezogen, sondern auf die
Angaben in den Intel-Manuals (da Du Intel ja schon vorher mit Glauben in
Verbindung gebracht hast).

> Die - ganz nebenbei be- merkt - weder mit Handbücher schreibenden
> iNTEL-Mitarbeitern noch mit mir etwas zu tun hat. Als CB-Funker sind
> mir sicher die üblichen Zahlenkürzel aus der Funkersprache bekannt,
> die sind aber ebenso aus einem - dem Rest der Welt unbekannten -
> Fachjargon entnommen wie Dein "386".

Fein erkannt. Nach Deinem Vorwurf, ich würde Abkürzungen in vollkommen
unüblicher und unverständlicher Weise gebrauchen, und nachdem ich
bemerkt hatte, dass http://xkcd.com/386/ eine Nummer hat, die hier jeder
(inklusive mir selbst) mit etwas anderem in Verbindung bringen würde,
konnte ich der Versuchung nicht widerstehen, deinen Vorwurf wahr zu
machen, indem ich "386" ohne Erklärung erwähne.

Bernhard Schornak

unread,
Dec 21, 2014, 7:03:11 AM12/21/14
to
Was sowohl bei AMD als auch bei iNTEL seit Ewigkeiten der Fall
ist. Bulldozer hat 4 Integer- und 4 Fliesskommapipes pro Kern,
wobei letztere bei AVX-Befehlen mit den 4 Fliesskommapipes des
zweiten Kerns der Einheit (Unit) zusammengeschaltet werden, in
den aktuellen iNTEL-Prozessoren werkeln mindestens drei (Sandy
Bridge) Integer- und sechs Fliesskommapipes pro Kern. Jede der
Pipes ist zwar für spezifische Aufgaben reserviert, simple OPs
können aber (zumindest beim Bulldozer) auf allen Pipes abgear-
beitet werden, z.B. MOV reg,reg und ähnliche.


> Nein, wir reden von einem Kern mit einer Pipeline.


Ach? Ausser Dir tut das eigentlich niemand, da seit mindestens
fünfzehn Jahren alle auf dem Markt angebotenen x86-Prozessoren
mindestens zwei Integer- und eine Fliesskommapipe haben:

http://arstechnica.com/features/2001/05/p4andg4e/
http://archive.arstechnica.com/cpu/3q99/k7_theory/k7-one-1.html


> In jedem Takt liest
> der Kern (bis zu) 4 Instruktionen und schiebt die in die Pipeline. Die
> werden dann dekodiert und in jedem Takt können (bis zu) 8
> Mikroinstruktionen weitergereicht werden. Die werden dann abgearbeitet,
> wobei manches parallel geht (zwei Additionen z.B.) manches umsortiert
> werden kann (z.B. können "spätere" Register-Operationen vorgezogen
> werden, während eine Lese-Operation auf das Memory wartet), manches
> spekulativ ausgeführt wird (Operationen hinter einem bedingten Sprung)
> und manches muss halt seriell ausgeführt werden.
>
> Und ja, das heißt, dass ein Kern zwei der Instruktionen, bei denen im
> Manual 0.5 steht, im gleichen Takt abarbeiten kann (und noch zwei
> andere). Generell kann man diese Zahlen (weder Throughput noch Latency)
> nicht einfach addieren, um herauszufinden, wie lange eine
> Instruktionssequenz dauert, weil da eben viel parallel abgearbeitet
> wird.
>
> (Bei Hyperthreading wird es noch ein bisschen komplizierter, aber das
> können wir ignorieren)


http://www.anandtech.com/show/4955/the-bulldozer-review-amd-fx8150-tested/2
http://www.realworldtech.com/haswell-cpu/4/

Jeglicher Kommentar erübrigt sich damit im Prinzip.

NUR: Kein Mensch addiert Durchsätze und Latenzzeiten eines und
des selben Befehls - es sei denn, er steht in zwei aufeinander
folgenden Zeilen des Quellcodes (z.B. zwei NOPs, die intern in
XCHG rAX,rAX umgewandelt werden).

UND: Aus einem Durchsatz von angeblich "0,5 Takten" lässt sich
ganz bestimmt nicht ableiten, dass neben diesem nach angeblich
0,5 Takten ausgegebenen Ergebnis simultan zusätzlich noch zwei
weitere Befehle im selben Takt und der selben Pipe verarbeitet
werden. Wie soll das physikalisch funktionieren?


>>>> BTW: Für mystische Zahlenspiele dürften sich in de.alt.astrologie
>>>> oder de.alt.paranormal sicher recht interessante Gesprächspartner
>>>> finden... ;)
>>>
>>> Das hat nichts mit Mystik zu tun. Man muss nur lesen und dabei das Hirn
>>> einschalten, Natürlich hilft es beim Lesen, wenn man davon ausgeht, dass
>>> sich die Autoren des Handbuchs etwas dabei gedacht haben und nicht mit
>>> der Einstellung "Intel-Mitarbeiter sind alle Volltrottel" herangeht.
>>
>> Für mich war dieses (von Dir ja geschickt herausgeschnippte)
>> Zitat Deines vorhergehenden Beitrags
>>
>>>> Damit bleibt mir nur noch "386" zu sagen, und damit meine
>>>> ich auch nicht den Intel-Prozessor.
>>
>> ein Musterbeispiel für Zahlenmystik.
>
> Du verstehst offensichtlich unter Zahlenmystik etwas anderes als ich.


Man könnte anhand der Sachlage durchaus darauf schliessen.


> Aber darauf hatte ich Deine Anmerkung nicht bezogen, sondern auf die
> Angaben in den Intel-Manuals (da Du Intel ja schon vorher mit Glauben in
> Verbindung gebracht hast).


Bitte bezieh Dich auf das, was ich geschrieben habe, und nicht
auf das, von dem Du glaubst, dass ich es unter Umständen hätte
gemeint haben könnte...

Peter J. Holzer

unread,
Dec 21, 2014, 7:14:38 AM12/21/14
to
On 2014-12-21 12:03, Bernhard Schornak <scho...@web.de> wrote:
> nach angeblich 0,5 Takten ausgegebenen Ergebnis

Du hast es noch immer nicht kapiert. Ich gebe es auf.

Bernhard Schornak

unread,
Dec 21, 2014, 8:21:18 AM12/21/14
to
Peter J. Holzer schrieb:


> On 2014-12-21 12:03, Bernhard Schornak <scho...@web.de> wrote:
>> nach angeblich 0,5 Takten ausgegebenen Ergebnis
>
> Du hast es noch immer nicht kapiert. Ich gebe es auf.


Mag daran liegen, dass ich nicht an Magie glaube, und Deine
bisherigen Ausführungen nicht angetan waren, zur Lösung der
diskutierten Streitpunkte beizutragen. Abgesehen davon kann
man nichts aufgeben, das man nie begonnen hat...
0 new messages