PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wieviel 16 Bit Arithmetik in heutigen Programmen?


GloomY
2003-09-28, 18:22:19
Wir haben seit Jahren 32 Bit Rechner, seit kurzem gibt es bereits 64 Bit Rechner. Daher scheint meine Frage etwas komisch zu sein, wie viel 16 Bit Arithmetik noch in heutigen Code vorhanden ist.

x86 kann ja Dank der Möglichkeit von partiellen Registerzugriffen auch 8 oder 16 Bit verarbeiten und nicht nur 32 Bit. Der Hintergrund, warum mich das Verhältnis (speziell von Integer-) Berechnungen mit 16 oder 32 Bit interessiert, ist folgender:

Dieser Artikel (http://developer.intel.com/technology/itj/q12001/articles/art_2.htm) auf der Intel HP beschreibt u.a. die Funktionsweise der double pumped ALUs. Über diese wurde schon recht viel spekuliert, aber dort (http://developer.intel.com/technology/itj/q12001/articles/art_2e.htm) steht es deutlich, wie das Ding funktioniert und aufgebaut ist:

http://developer.intel.com/technology/itj/q12001/images/art_2_fig7.gif

Als Erklärung steht u.a. folgendes dort:The processor does ALU operations with an effective latency of one-half of a clock cycle [...]

In the first fast clock cycle, the low order 16-bits are computed and are immediately available to feed the low 16-bits of a dependent operation the very next fast clock cycle. The high-order 16 bits are processed in the next fast cycle, using the carry out just generated by the low 16-bit operationHier handelt es sich also um zwei 16 Bit Addierer, die mit doppeltem Prozessortakt laufen. 32 Bit Operationen brauchen allerdings zwei doppelte Prozessortakte, also einen normalen Prozessortakt.

Der Durchsatz bei 32 Bit Arithmetik ist also trotz zweifach getakteten ALUs trotzdem nur eine Operation pro Prozessortakt. Lediglich 16 Bit Operationen können mit einen halben Prozessortakt und damit doppelter Geschwindigkeit ausgeführt werden.

Es hat mich schon immer etwas gewundert, dass Intel nur von doppelt so schnell getakteten ALUs geredet hat und nie auch nur das eigentlich interessante - nämlich den Durchsatz - erwähnt hat. Schneller sind diese ALUs ja im Vergleich zu normalen, da sie 16 Bit Additionen ja schneller ausführen können (halber Prozessortakt) und sie bei 32 Bit gleich schnell sind.
Die Frage ist bloss, wie viele 16 Bit Artihmetik noch in heutigen Programmen verwendet wird. Gibt es dafür Statistiken? Was sagen die erfahrenen ASM-Progger hierzu? Immer EAX, EBX usw. oder auch mal nur AX, BX oder sogar nur AL und AH... ? ;)

Gast
2003-09-28, 22:53:35
Die Frage ist ja auch ob die Daten hinter der ALU auch so schnell weiterverarbeitet werden könnten, wie diese bei 16 Bit liefern könnte bzw ob man schnell genug Daten reinbekommt :D

Im Prinzip ist jeder Programmierer natürlich faul. D.h er geht nur so tief, wie er unbedingt gehen muss. Wenns notwendig ist, wird er auch die "Teil"register nutzen, wenn es relativ zur Zeit und Zielsetzung lohnend ist. Ich finds aber meistens sehr unübersichtlich zu handhaben und meistens auch überflüssig ;) . Ausserdem liefern die SSE Einheiten bei den meisten Operationen selbst bei einzelnen Daten eh einen besseren Durchsatz und ist über die Intrinsics viel viel einfacher anzusprechen als wenn ich mit Inlineassembler anfangen muss. Die Registerverwaltung übernimmt dabei freundlicherweise der Compiler.
Ich denk mal so: Umso optimierter der Code ist umso mehr 16 Bitanteil wird man drin finden. Andererseits kann bei falscher Verwendung das auch Performance kosten (Stichwort: Data Alignment). Und dabei einen Fehler zu machen kostet wesentlich mehr als einen halben Prozessortakt ;(
Das ganze ist immer ne Gradwanderung zwischen möglichst wenig Daten zu produzieren und andererseits dem Prozessor, das in ihm passenden Stückchen zu servieren (was auch oft durch Aufblähen der Daten geschieht :/ )

BlackBirdSR
2003-09-29, 00:24:39
Original geschrieben von GloomY
[...]


hmm
add EAX, EBX
add EAX, ECX in einem Cycle? ;)

Ich glaube es ging von Anfang an nicht darum, 2 32Bit Operationen gleichzeitig auszuführen
Die beiden Fast-ALUs ermöglichen es, 2 abhängige Operationen in einem Takt anzusetzen.

Die unteren 16Bit werden in im ersten Takt der Fast-ALU (FClock) addiert, und stehen noch im selben CPU Taktzyklus (MClock) bereit.
Die zweite Instruktion, kann nun bereits diese unteren 16Bit nutzen (im 2. FClock Cycle), und wiederum den unteren Teil des Ergebnises bilden.

Währenddessen wird der obere Teil gebildet. Klar ist die 32 Operation damit erst nach 1 Takt fertig, und nicht nach 1/2, dafür ist die nächste Addition schon fast fertig.

Da man hier die Addition ja über 2 Pipeline stages verteilt, ist es schon ein schäner Bonus, dass man keinen Takt Pause einlegen muss, und die CPU trotzdem so hoch takten kann.

Yet Intel has clearly indicated that the Willamette can cascade the result of an add instruction into a subtraction and then through a move instruction and finally feed an xor instruction in just two clock cycles

Man sieht also, die beiden Fast-ALUs sind auch nur dann richtig effektiv, wenn man passende Instruktionen findet. Sicherlich keine leichte Aufgabe.
Dafür sollten sie billiger, und viel weniger kritisch sein, was den Einfluss auf den CPU Takt angeht.

und wehe jetzt kommt wieder einen von wegen nur 3µOps des Trace Caches :bad1: ;D

GloomY
2003-09-29, 16:48:57
Original geschrieben von Gast
Die Frage ist ja auch ob die Daten hinter der ALU auch so schnell weiterverarbeitet werden könnten, wie diese bei 16 Bit liefern könnte bzw ob man schnell genug Daten reinbekommt :DIntel wird Dank großer Bandbreiten bei L1, L2 und RAM prinzipiell eher weniger Probleme mit dem Beschaffen von großen Datenmengen haben.

Beim Weiterverarbeiten hat Intel ja z.B. selbst in ihrem Dokument erwähnt, dass die unteren 16 Bit sofort an den L1 Cache gehen können (um den Line-Index zu vergleichen), wenn das Ergebnis eine Adresse darstellt. Ich nehme an, dass Intel schon noch etliche andere ähnliche Optimierungen hierfür eingebaut hat.
Original geschrieben von Gast
Im Prinzip ist jeder Programmierer natürlich faul. D.h er geht nur so tief, wie er unbedingt gehen muss. Wenns notwendig ist, wird er auch die "Teil"register nutzen, wenn es relativ zur Zeit und Zielsetzung lohnend ist. Ich finds aber meistens sehr unübersichtlich zu handhaben und meistens auch überflüssig ;)Das können ja auch die Compiler erledigen, wenn sie gut optimiert sind. Der Intel Compiler ist ja gegenüber allen anderen ein ganzes Stück in der Performance vorraus und keiner weiss eigentlich warum ;)
Original geschrieben von Gast
Ausserdem liefern die SSE Einheiten bei den meisten Operationen selbst bei einzelnen Daten eh einen besseren Durchsatz und ist über die Intrinsics viel viel einfacher anzusprechen als wenn ich mit Inlineassembler anfangen muss.SSE muss nicht immer schnell sein. Bei gemischten FP/Int Code wäre es nicht sehr nützlich, die Int Berechnungen durch die FP/SSE Pipeline ausführen zu lassen. Imho würde man hier die Möglichkeit einer besseren Parallelität verschenken, weil dann alles nur noch über die FP/SSE Einheit läuft.
Original geschrieben von Gast
Ich denk mal so: Umso optimierter der Code ist umso mehr 16 Bitanteil wird man drin finden.
Andererseits kann bei falscher Verwendung das auch Performance kosten (Stichwort: Data Alignment). Und dabei einen Fehler zu machen kostet wesentlich mehr als einen halben Prozessortakt ;(
Das ganze ist immer ne Gradwanderung zwischen möglichst wenig Daten zu produzieren und andererseits dem Prozessor, das in ihm passenden Stückchen zu servieren (was auch oft durch Aufblähen der Daten geschieht :/ ) Ack.

GloomY
2003-09-29, 17:12:35
Original geschrieben von BlackBirdSR
hmm
add EAX, EBX
add EAX, ECX in einem Cycle? ;)

Ich glaube es ging von Anfang an nicht darum, 2 32Bit Operationen gleichzeitig auszuführenSo wird es aber leider vom Marketung verkauft :(
Original geschrieben von BlackBirdSR
Die beiden Fast-ALUs ermöglichen es, 2 abhängige Operationen in einem Takt anzusetzen.

Die unteren 16Bit werden in im ersten Takt der Fast-ALU (FClock) addiert, und stehen noch im selben CPU Taktzyklus (MClock) bereit.
Die zweite Instruktion, kann nun bereits diese unteren 16Bit nutzen (im 2. FClock Cycle), und wiederum den unteren Teil des Ergebnises bilden.

Währenddessen wird der obere Teil gebildet. Klar ist die 32 Operation damit erst nach 1 Takt fertig, und nicht nach 1/2, dafür ist die nächste Addition schon fast fertig.Daran hatte ich auch nicht gedacht. Das würde heissen, dass zwei aufeinanderfolgende 32 Bit Additionen schon nach 1,5 Takten fertig sind, wenn man dieses "Result-Forewarding" (=Ergebnis der ALU wieder an den Eingang anlegen) verwendet?
Original geschrieben von BlackBirdSR
Da man hier die Addition ja über 2 Pipeline stages verteilt, ist es schon ein schäner Bonus, dass man keinen Takt Pause einlegen muss, und die CPU trotzdem so hoch takten kann.Meinst du mit "Takt" einen schnellen, also halben CPU Takt?
Original geschrieben von BlackBirdSR
Man sieht also, die beiden Fast-ALUs sind auch nur dann richtig effektiv, wenn man passende Instruktionen findet. Sicherlich keine leichte Aufgabe.Jep. Ansonsten würde man z.B. beim SPEC Int 2000 auch eine viel stärkere Performance sehen. Mich hat das eh schon immer gewundert, warum da trotz zwei dp-ALUs und einer normalen ALU zusammen mit den hohen Taktraten nicht viel mehr rausgekommen ist.
Original geschrieben von BlackBirdSR
Dafür sollten sie billiger, und viel weniger kritisch sein, was den Einfluss auf den CPU Takt angeht.Billiger glaube ich mit Sicherheit nicht. Diese ALUs sind so klein wie möglich angeordnet, sonst könnten sie nicht mit doppeltem Prozessortakt arbeiten. Das Design ist mit großer Sicherheit hand-optimiert und damit sehr teuer.

BlackBirdSR
2003-09-29, 17:28:04
Original geschrieben von GloomY
Daran hatte ich auch nicht gedacht. Das würde heissen, dass zwei aufeinanderfolgende 32 Bit Additionen schon nach 1,5 Takten fertig sind, wenn man dieses "Result-Forewarding" (=Ergebnis der ALU wieder an den Eingang anlegen) verwendet?

Sieht so aus.. wobei das wirklich der Hauptverwedungszweck der Fast-ALUs zu sein scheint. Abhängige Operationen schneller abzuarbeiten, also deren Durchsatz zu erhöhen. Natürlich nur für bestimmte Befehlesfolgen, was das Ganze wieder etwas weniger "cool" erscheinen lässt.

Original geschrieben von GloomY
Meinst du mit "Takt" einen schnellen, also halben CPU Takt?

Nein einen CPU Takt. Die Addition ist ja zwangsläufig auf 2 Pipeline Stufen verteilt. Bei einer normalen ALU müsste man hier 1 Takt warten, bevor man die 2. Addition losschicken kann. Ist anscheinend alles so ausgelegt, dass die vielen Pipeline Stufen nicht ganz so großen Schaden anrichten.

Original geschrieben von GloomY
Jep. Ansonsten würde man z.B. beim SPEC Int 2000 auch eine viel stärkere Performance sehen. Mich hat das eh schon immer gewundert, warum da trotz zwei dp-ALUs und einer normalen ALU zusammen mit den hohen Taktraten nicht viel mehr rausgekommen ist.


Weiss auch nicht was Intel damit wirklich erreichen wollte, wenn es nicht um den Takt ging.

Original geschrieben von GloomY
Billiger glaube ich mit Sicherheit nicht. Diese ALUs sind so klein wie möglich angeordnet, sonst könnten sie nicht mit doppeltem Prozessortakt arbeiten. Das Design ist mit großer Sicherheit hand-optimiert und damit sehr teuer.

also billiger als 4 richtige ALUs ist es schon wenn man den Aufwand in betracht zieht, den es kosten würde, die CPU dann totzdem so hoch zu takten. Zudem sind es ja keine vollständigen Addierer. Ich kann mir schon vorstellen, dass eine ähnliche schnelle Alternative teuer geworden wäre (ob nun in Geld, Leistung, Takt oder Transistorcount gerechnet)

micki
2003-09-29, 19:08:46
es muss keine 16bit arithmetik sein, man kann wohl auch add Eax,Ecx rechnen und falls dort die obersten 16-bit 1 oder 0 sind, wird 16bit gerechnet

so läuft das z.B. bei der ARM cpu vom gba, je nachdem ob 8 16 oder 32 bit in den nicht 0/1 sind, braucht der für eine multiplikation 1,2 oder 3 cycles.

natürlich ist das nur ne vermutung auf die intelchips bezogen, aber wieso sollten die das nicht können, wenn soeine billige arm cpu das kann?

gruesse
micki

Gast
2003-09-30, 09:08:11
Original geschrieben von GloomY
Mich hat das eh schon immer gewundert, warum da trotz zwei dp-ALUs und einer normalen ALU zusammen mit den hohen Taktraten nicht viel mehr rausgekommen ist.

Leider kann der decoder nur 3 befehle pro takt nachschieben kann, da hatt Intell was gepennt beim design ;)

BlackBirdSR
2003-09-30, 09:33:11
Original geschrieben von Gast
Leider kann der decoder nur 3 befehle pro takt nachschieben kann, da hatt Intell was gepennt beim design ;)

:...( :tgv:

Der Decoder schiebt 1. IA32 Instruktion nach, der Trace Cache 3µOps, und der Scheduler 6µOps.
Es ist also mehr als Genug da ;)

Gast
2003-09-30, 11:09:26
Original geschrieben von BlackBirdSR
:...( :tgv:

Der Decoder schiebt 1. IA32 Instruktion nach, der Trace Cache 3µOps, und der Scheduler 6µOps.
Es ist also mehr als Genug da ;)

urgs,war noch früh am morgen, wie man an meinem satz sieht ;)

Hm,wenn ich das richtig sehe, werden die scheduler doch von dem trace cache "gefüttert" (und dem decoder)?
Der P4 könnte dann im günstigsten fall (Instruktionen schon im Trace cache), doch auch nur 3 Instruktionen in Richtung der ALU´s schicken(welche 5 Instruktionen aufnehmen könnten 2DP-Alu´s + 1 ALU, 4 simple Integer Instuktionen + 1 Integer/shift/rotate).
Denkfehler bei mir?

zeckensack
2003-09-30, 17:37:17
Original geschrieben von micki
es muss keine 16bit arithmetik sein, man kann wohl auch add Eax,Ecx rechnen und falls dort die obersten 16-bit 1 oder 0 sind, wird 16bit gerechnet

so läuft das z.B. bei der ARM cpu vom gba, je nachdem ob 8 16 oder 32 bit in den nicht 0/1 sind, braucht der für eine multiplikation 1,2 oder 3 cycles.

natürlich ist das nur ne vermutung auf die intelchips bezogen, aber wieso sollten die das nicht können, wenn soeine billige arm cpu das kann?

gruesse
micki Wenn das Diagramm einen Bezug zur Realität hat (;)), dann ist die 'obere' Hälfte sowieso nicht alleine nutzbar. Würde also nichts bringen. Die 'untere' Hälfte muß frei sein, um eine Instruktion starten zu können.

Für zwei voll getrennte 16 Bit-ALUs fehlen am Ausgang Muxe, die die Bits der ALUs in die jeweils andere Hälfte des Zielregisters umleiten könnten.

BlackBirdSR
2003-09-30, 19:21:13
Original geschrieben von Gast
urgs,war noch früh am morgen, wie man an meinem satz sieht ;)

Hm,wenn ich das richtig sehe, werden die scheduler doch von dem trace cache "gefüttert" (und dem decoder)?
Der P4 könnte dann im günstigsten fall (Instruktionen schon im Trace cache), doch auch nur 3 Instruktionen in Richtung der ALU´s schicken(welche 5 Instruktionen aufnehmen könnten 2DP-Alu´s + 1 ALU, 4 simple Integer Instuktionen + 1 Integer/shift/rotate).
Denkfehler bei mir?

stimmt schon, dass der Trace Cache nur 3µOps/Takt ausspuckt. Das alleine reicht aber nicht aus, um schon zu bestimmen, was die CPU nun leisten kann.

Zuerst, liegt der durchschnittliche Instruktionsdurchsatz wahrscheinlich irgendwo so zwischen 1.7 und 2.2. (Bin nicht sicher wie der Wert beim P4 genau aussieht.. wahrscheinlich eher niedriger als höher).
Schuld ist der allseits heissgeliebte Begriff "ILP" (Muh-die-Kuh, ist da recht fitt). Abhängigkeiten der Befehle untereinander, Pipeline Stalls, Limitierungen der Hardware, die eine Instruktion nur alle 2 Takte zulassen etc etc... - sorgen dafür, dass man nie an den Maximalwert herankommt.
Besonders die beiden Fast ALUs sind ständig darauf angewiesen, bestimme Befehlsfolgen vorgesetzt zu bekommen. Die meiste Arbeit dürfte die Slow-ALU erledigen. Von 5µOps pro Takt kann man da glaube ich nicht sprechen.

Der P4 könnte also 6 µOps an die Ausführungseinheiten ausgeben, die kann er aber nicht wirklich alle in einem Takt ansetzen. Währenddessen werden 3µops nachgeschoben. Es ist nicht sehr wahrscheinlich, dass der P4 am Limit läuft, und ständig auf Instruktionen warten muss.
Das beweist z.B Hyperthreading. Wären die 3µOps wirklich zu wenig, hätte man wohl kaum noch einen Gewinn, bzw schwere Performanceeinbußen. Schließlich muss man jetzt Instruktionen zweier unabhängiger Threads gleichzeitig die Pipeline runter schicken.


kann natürlich sein dass ich hier falsch liege.. also nicht für bare Münze nehmen *g*