Archiv verlassen und diese Seite im Standarddesign anzeigen : [PCN] Der Prozessor - Sammel und Diskussionsthread
Willkommen im Diskussionsthread ueber den Prozessor des Projektes Carpe Noctem.
Bevor ihr weiter lest, solltet ihr sicher gehen, folgende Posts gelesen zu haben, damit ihr wisst, worum es hier genau geht.
Was ist das PCN ? (http://www.multimediaxis.de/showthread.php?t=67162)
Wie wird hier diskutiert, was sollen wir machen ? (http://www.multimediaxis.de/showthread.php?p=1268509#post1268509)
Und wo stehen die Grundlagen ? (http://www.multimediaxis.de/showthread.php?t=67851)
****************************************************************
Wichtige Zusammenfassungen und Verweise werden im Verlauf des Threads hier im ersten Post ergaenzt.
* bisher noch nichts bekannt oder festgelegt *
Ok, dann fangen wir am besten erst einmal mit ein paar grundlegenden Dingen an.
Wir muessen uns, wenn wir einen Prozessor bauen bzw emulieren wollen, natuerlich fragen, was genau ein Prozessor ist, und worin seine Aufgabe besteht. Diese auf den ersten Blick triviale Frage enthaellt aber schon sehr viel, ueber das es genauer nachzudenken gilt.
Der Wikipedia zu Folge ist ein Prozessor (http://de.wikipedia.org/wiki/Prozessor_(Hardware))
eine Recheneinheit eines Computers, der per Software andere Bestandteile steuert.
Die grundlegende Eigenschaft des Prozessors ist die Programmierbarkeit, das Verhalten des Prozessors wird dabei von Programmen in Form von Maschinencode bestimmt. Hauptbestandteile des Prozessor sind die Register, das Rechenwerk (ALU), das Steuerwerk und der Speichermanager (MMU) der den Arbeitsspeicher verwaltet. Zu den zentralen Aufgaben des Prozessors gehören arithmetische Operationen, das Lesen und Schreiben von Daten im Arbeitsspeicher, sowie das Ausführen von Sprüngen im Programm.
Aus dem hier schoen zusammengefassten folgen somit einige Dinge:
* Er muss aus dem Hauptspeicher lesen koennen
* Er muss in den Hauptspeicher schreiben koennen
* Er muss einen bestimmten Befehlssatz kennen
* Er muss Daten verarbeiten koennen
* Er muss ein beliebig ersetzbares, variables Programm abarbeiten können.
Wie man dem Artikel und seinem logischen Denkvermoegen sowie seinem Grundwissen entnehmen kann, verfuegen verschiedene Prozessoren ueber verschiedenste Parameter, auf die wir uns im folgenden einigen muessen. Bei einigen Punkten ist sicherlich nicht jedem klar, was die Begriffe bzw Konzepte bedeuten. Kleine Erklaehrungen und Tutorials sind also wuenschenswert. Wer etwas weiss laesst die anderen einfach daran teilhaben, und wer etwas wissen will, fragt einfach.
* Wieviel Bit soll unsere Architektur haben
* Wieviele Register hat unser Prozessor
* Wollen wir einen einfachen oder einen komplexen Befehlssatz (RISC (http://de.wikipedia.org/wiki/Reduced_Instruction_Set_Computing) / CISC (http://de.wikipedia.org/wiki/CISC))
* Welche Befehle braucht ein Prozessor unbedingt
* Welche Byteordnung haben Multibytedatentypen
* Wie repraesentieren wir komplexere Datenstrukturen, wie z.B. Gleitkommazahlen
* Soll unser System ein Multiprozessorsystem sein
* Wird es Interrupts geben, und wie behandelt man sowas
* Was sind Ports und wie repraesentieren wir diese
* uvm.
Als naechstes waere zu klaehren, wie die Implementierung des Prozessors erfolgen soll. Natuerlich waere es schneller, wenn unser Prozessor ein 1:1 Nachbau eines bestehenden Prozessors waere, und man einfach den Maschienencode durchschleifen koennte. Dann koennte man allerdings nicht davon sprechen, einen eigenen Prozessor zu haben, und waere an die Hardwarevorgaben anderer gebunden. Daher denke ich, ist es klar, wie unser Prozessor zu funktionieren hat. Unser Prozessor ist im Grund eine endlosschleife im zu schreibenden Interpreter (unserer VM), die einen Maschinencodebefehl und ggf dazugehoerige Parameter (z.B. aus einer Datei, oder spaeter unserem Arbeitsspeicher) ausliest, in einer internen Funktionstabelle nachsieht, was der Code zu bedeuten hat, dementsprechend bestimmte Aktionen durchfuehrt und sich danach dem naechsten Code zuwendet. Systeme wie den BUS, FPU oder die direkte Speicherkommunikation wuerde ich einfach die VM emulieren lassen, so dass der Prozessor nach aussenhin als Blackbox betrachtet werden kann. Eine solche Vorgehensweise ist natuerlich langsamer, bietet uns aber alle freiheiten, die wir wollen. Geschwindigkeit ist also ersteinmal nicht das entscheidende Problem. Diese kann eventuell spaeter ueber optimierte Routinen noch maximiert werden.
Wie man an diesem Konzept bereits sieht, ist die Kommunikation mit dem Hauptspeicher untrennbar mit dem Prozessor verbunden, denn wo sollte das Programm stehen, wenn nicht im Arbeitsspeicher. Ich schlage vor, dass wir fuer den Anfang den Arbeitsspeicher als eine fixerte Datei dem Prozessor ueber die VM zufuehren und am Ende des Programmes den Arbeitsspeicher durch die VM in eine Datei schreiben lassen, welche wir dann per Hand auswerten koennen.
Ich freue mich auf euere Ideen und Eindruecke zum bereits gesagten und auf viele weitere Vorschlaege und Aspekte, die es noch zu bedenken gibt. Die Diskussion ist eroeffnet.
dead_orc
12.04.2006, 10:45
Uff. *Informationoverkill*
Du wolltest Fragen, du bekommst Frage:
- Sehe ich es richtig, dass unser Programm, das den Prozessor emuliert, quasi ein Interpreter für unseren Maschinencode ist?
- Wie wirken sich die Anzahl der Bits auf den Rest aus?
So wie ich das verstehe bisher, würde ich zu deinen Fragen sagen:
- Wenn wir dem Prozessor einen kleinen Befehlssatz verpassen, ist es für uns im Moment leichter, den Prozessor zu entwickeln, aber es wird dann schwerer, Programme (Compiler, whatever) zu schreiben.
Tja, meine Meinung/Ansicht ^^°
drunken monkey
12.04.2006, 11:57
OK, ich habe ja schon gesagt, dass ich nicht so viel AHnung von Low-Level-zeugs habe, aber hier mal meine Meinung zu ein paar Sachen:
* Wie repraesentieren wir komplexere Datenstrukturen, wie z.B. Gleitkommazahlen
Nach dem IEEE-Standard, würde ich mal sagen, mit Single und Double. (Wikipedia-Artikel (http://en.wikipedia.org/wiki/IEEE_floating-point_standard), für die gänzlich Ahnungslosen ;)) Ob wir "Extended"-Versionen von Single und Double reinnehmen ist allerdings imo schon fraglich, halte ich für unnötig.
Mit RISC/CISC kenne ich mich nicht so aus, aber wäre RISC auf einem virtuellen Computer überhaupt möglich bzw. genauso effizient? Normalerweise wird das doch afaik gleich fix verlötet, wodurch die Geschwindigkeit erhöht wird. Das ist ja auf einer virtuellen Maschine nicht wirklich möglich.
Falls das aber kein Problem/kompletter Blödsinn meinerseits ist, wäre ich für RISC, um den Geschwindigkeitsverlust bei dem von dir vorgeschlagenen "Black Box"-Verhalten auszugleichen.
So, meine Meinung zu allen Fragen, von denen ich auch nur ein wenig Ahnung habe! ^^' Hoffentlich ist wenigstens das nicht kompletter Blödsinn, aber wie heißt's so schön:
"You live and you learn. At any rate, you live." DNA
Jesus_666
12.04.2006, 12:37
Hier mal meine Meinungen zum grundlegenden Design:
Bittigkeit: 16 bis 64. Alles andere würde IMO nicht soo toll sein (niedrige Bittigkeit) oder zu zu viel Aufwand führen (hohe Bittigkeit). Das ist aber kein generelles No-go, nur eine Empfehlung.
Register: Mehr Register bedeuten höhere Leistungsfähigkeit, aber auch größeren Aufwand. Ich denke, wir sollten beim Prozessor schon die Grundlegenden Fakten des Computerdesigns im Hinterkopf behalten. (In diesem Fall: Register sind viel teurer als on chip-Cache, der viel teurer als RAM ist, der viel teurer als Festepeicher ist.)
Befehlssatz: RISC. Selbst die alte CISC-Architektur IA32 hat mitlerweile ein RISC mit CISC-Emulation; außerdem werden bei CISCs oft die erweiterten Befehle kaum genutzt. Und RISC bedeutet eine einfachere Prozessorlogik.
Befehle: (Ich erhebe keinen Anspruch auf Vollständigkeit!)
Genereller Kram: NOP (tut nichts), INTER (Software Interrupt)
Arithmetik: ADD (Addition), SUB (Substraktion), MUL (Multiplikation), DIV (Division)
Boole'sche Logik: AND, OR, XOR, NOT
Branching: BEQ (Branch on equal), BNE (Branch on not equal), BGTZ (Branch on greater than zero), BLTZ (Branch on lesser than zero), BGEZ (Branch on greater than or equal to zero), BLEZ (Branch on less than or equal to zero)
Sprünge: J (Jump)
Speicherzugriffe: LOAD, STORE
Bitshifts: SLZ (Shift left, fill with zeroes), SRZ (Shift right, fill with zeroes), SLO (Shift left, fill with ones), SRO (Shift right, fill with ones), ROL (Rotate Left), ROR (Rotate Right)
Byteordnung: Big-endian. Einziger Grund: Das Internet Protocol ist big-endian.
Darstellung von Fließkommazahlen: Als IEEE-Fließkommazahlen natürlich.
Multiprocessoring: Führt zusätzliche Komplexität ein, würde ich u.U. erst in einer späteren Version einbauen.
Interrupts: Geht es überhaupt ohne? Die Behandlung sollte wie bei anderen Prozessoren auch ablaufen: Stack sichern, Behandlungsroutine durchlaufen lassen, zurückspringen.
Ports: ...
Noch ene Anmerkung: Der Prozessor sollte clocked sein - sprich, er sollte mit einem festen Takt arbeiten. Es ist möglich, Prozessoren auch ohne Referenztakt zu bauen, dann arbeiten die Komponenten unterschiedlich schnell, nur ist das komplizierter als mit festem Takt.
Maisaffe
12.04.2006, 12:43
Noch ene Anmerkung: Der Prozessor sollte clocked sein - sprich, er sollte mit einem festen Takt arbeiten. Es ist möglich, Prozessoren auch ohne Referenztakt zu bauen, dann arbeiten die Komponenten unterschiedlich schnell, nur ist das komplizierter als mit festem Takt.
Das PCN soll einen Prozessor richtig emulieren?
Bei VMWare übernimmt der Emulator 1:1 den Prozessortakt, bzw. reicht ihn durch - soweit meine Erfahrung.
Sollte das Ding mal gehen hätte ich garantiert nichts gegen einen festen (einstellbaren) Takt - aber wird das nicht extremst kompliziert?
Nur ne Frage nebenbei. ;)
Gut, mein Senf:
Bittigkeit: 32 oder 64. 16 halte ich für veraltet.
Register: Gute Frage, ich denk, das kommt ganz auf die Arbeitsweise an. Ich würde sagen, die nötigen Register, die wir zur Steuerung brauchen und mindestens zwei, die groß genug sind, um den größten nativen Datentyp (8 Byte?) aufzunehmen
Befehlssatz: RISC. Grade im Moment sollte uns die überragende Leistung der Playstation 3 zeigen, wozu RISC Prozessoren fähig sind.
Befehle: Dito mit Jeez.
Byteorder: Wohl eher Big-endian, aus dem gleichen Grund, den Jeez genannt hat. Allerdings sind Little-endians für den Menschen leichter lesbar, weil wir das eher gewohnt sind. Das würde uns das Debugen deutlich erleichtern.
Fließkommazahlen: IEEE-konform
Multiprocessoring: Später vielleicht
Interrupts: Was gibts für Alternativen?
Ports: Hat irgendjemand gutes Referenzmaterial?
Ich würde übrigens empfehlen, möglichst wenig spezielles Referenzmaterial über Prozessorarchitekturen zu sammeln. Sonst haben wir am Ende (wenn auch unbeabsichtigt) einfach eine Mischung aus x86 und PPC.
Man koentne auch ueber eine Gleitzahlenrepraesentation im Dezimalsystem, vorgeschlagen im IEEE854 bzw IEE754r (http://de.wikipedia.org/wiki/IEEE_754r), einfuehren. Wenn wir von einem 32bittigen System abweichen koennte das sogar eventuell fuer eine selbstgebaute FMU einfacher zu handhaben sein ...
Im Grunde kommen wir bei allen Bitbreiten ausser 32bit in Bedraengnis, da nicht jeder nativen 64bit support hat. Das heisst, man muesste die Rechenoperationen fuer Gleitkomma- und Ganzzahlen in jedem Fall selber schreiben, wenn wir nicht 32bit benutzen wollen. Trotzdem wuerde ich vorschlagen, von 32bit wegzugehen, einfach aus dem Grund, dass wir sonst ja auch einfach zum Prozessor durchschleifen koennten. Wenn wir allerdings alles selber implementieren, dann haben wir viel groessere Freiheiten.
Ich habe da eventuell (auch im Hinblick auf eventuelle Kompatibilitaet mit unserer spaeteren Graphikkarte) vielleicht an ein 96bit System gedacht. Das haette den Vorteil, das man sowohl in Zwei-, Drei-, Vier-, Sechs-, Acht- und Zwoelfbyteblöcken ohne Padding und Aligning arbeiten kann. Ausserdem gibt uns ein 96bit System Datentypen mit hohen genauigkeiten, Addressierung von nahezu unbegrenztem Speicher (so koennte man z.B. jedem Prozess muehelos seinen eigenen Speicherraum geben, indem man die Addressen mit der Prozessnummer padded, und diese dann auf den echten Ram mappt) und genuegend Variablilitaet auch fuer komplexe Machienencodebefehle.
Was mich auch zu dem Punkt RISC vs CISC bringt. Natuerlich haben RISC Prozessoren Geschwindigkeitsvorteile gegenueber CISC wenn es um die Hardwarerepraesentation geht. Andererseits stellt sich das Problem bei unserem Prozessor ja nicht, sondern kehrt sich fast ins gegenteil. Denn unser virtueller Prozessor verursacht bei jedem Befehl viele Befehle in unserem realen Rechner. Da sind Case Statements auszuwerten, Unterprogramme aufzurufen usw. Das heisst, mit einem (reinen) RISC Prozessor verursachen wir wahrscheinlich viel mehr Wartezeit, da viel mehr Operationen auszufuehren sind, die man bei einem CISC in einem Schritt kodieren kann.
Ein Beispiel. Nehmen wir einen ASM Befehl, der einen Speicherbereich (DX) auf einen anderen Speicherbereich kopieren soll (EX), und zwar so viele Byte, wie in CX gespeichert sind.
Mit einem RISC saehe das im Code im Prinzip so aus:
::label ; Begin der Schleife
LOAD AX, DX ; Lade in AX, was an der Addresse in DX steht
SAVE EX, AX ; Schreibe an die Addresse aus EX, was in AX steht
INC DX ; Ruecke DX ein Byte weiter
INC EX ; Ruecke EX ein Byte weiter
DEC CX ; Anzahl noch zu kopierender Bytes verkleinern
CMP CX, 0 ; Ist CX größer als Null ?
JGT label ; Wenn ja, springe an den Anfang der Schleife
Unser Prozessor muesste also 7 Befehle parsen, 7 Mal in seiner Befehlstabelle nachschlagen, 11 Mal auf den RAM zugreifen (da unsere Register ja auch im RAM liegen, wenn wir nicht in ASM optimieren sondern mit einer Hochsprache arbeiten).
Bei einem CISC Befehlssatz koennte man das viel schneller und eleganter loesen:
CPY EX, DX
Und hinter dem ominoesen CPY Befehl verbirgt sich in unserem Interpreter dann folgende Zeile:
memcpy( (void*) Registers["EX"], (void*) Registers["DX"], Registers["CX"] );
Man koennte als die ganze Arbeit des CISC Befehles durch schon vorgefertigte betriebssystemnahe und optimiere Hochsprachenfunktionen ersetzen. Effektiv sollte das also schneller sein.
Was die Register angeht haben wir auch nicht die Probleme, die echte Prozessorenbauer haben. denn unsere Prozessoren koennten beliebig viele Register haben. Allerdings koennte man der Einfachheit halber wie bei den RISC Prozessoren statt einer variablen Befehlskettenlaenge eine mit fixierter Breite verwenden, und damit das Parsen erleichtern.
Ich wuerde also Vorschlagen, sich an der RISC Architektur mit ihren fixierten Befehlsbreiten und hohen Registerzahlen (teilweise ueber 256) zu orientieren, jedoch auch einen erweiterten CISC Befehlssatz mit komplexen Routinen anzubieten, die dann im Intgerpreter schnell und kompakt nativ durchgefuehrt werden koennen. Denn man sollte bedenken, in unserem Fall kann man einen CISC ohne Geschwindigkeitseinbusse als RISC betreiben, aber nicht umgekehrt.
Ich würde würde mir die Ziele mal nicht zu hoch stecken. Man sollte auch immer im Hinterkopf haben, dass alles mal umgesetzt werden soll. Ein paar Wikiartikel lesen, alles drei Nummern besser als dort beschrieben vorschlagen und dann hoffen, dass es irgendwer umsetzt, wäre unsinnig.
Ich würde erstmal eine 32Bit-Architektur anvisieren. Mit nicht zu vielen Registern, Little-Endian Byteanordnung und einem einfachen Befehlssatz. An einem CISC zu arbeiten, wobei es noch kein vergleichbares RISC gibt, finde ich nicht sehr klug. Wie soll das dann aussehen? Komplexe Befehle hat der Prozessor und einfache nicht? Nein, erstmal sollte ein einfacher Befehlssatz existieren, bevor man einen komplexen entwickelt. Das ist die logischere Reihenfolge.
freundliche Grüße, Rolus
Jesus_666
12.04.2006, 19:46
Ich habe da eventuell (auch im Hinblick auf eventuelle Kompatibilitaet mit unserer spaeteren Graphikkarte) vielleicht an ein 96bit System gedacht. Das haette den Vorteil, das man sowohl in Zwei-, Drei-, Vier-, Sechs-, Acht- und Zwoelfbyteblöcken ohne Padding und Aligning arbeiten kann. Ausserdem gibt uns ein 96bit System Datentypen mit hohen genauigkeiten, Addressierung von nahezu unbegrenztem Speicher (so koennte man z.B. jedem Prozess muehelos seinen eigenen Speicherraum geben, indem man die Addressen mit der Prozessnummer padded, und diese dann auf den echten Ram mappt) und genuegend Variablilitaet auch fuer komplexe Machienencodebefehle.Okay... Allerdings ist natürlich zu bedenken, daß das mit den Speicherräumen sich relativiert - den privaten Specherraum haben Prozesse seit dem 80386 (virtuell) und physikalisch ist das natürlich alles illusionär.
Und natürlich brauchen wir dann wesentlich mehr LOAD- und STORE-Befehle: Für Bytes, 16 Bits, 32 Bits, 48 Bits, 64 Bits, 72 Bits, 96 Bits.
Was mich auch zu dem Punkt RISC vs CISC bringt. Natuerlich haben RISC Prozessoren Geschwindigkeitsvorteile gegenueber CISC wenn es um die Hardwarerepraesentation geht. Andererseits stellt sich das Problem bei unserem Prozessor ja nicht, sondern kehrt sich fast ins gegenteil. Denn unser virtueller Prozessor verursacht bei jedem Befehl viele Befehle in unserem realen Rechner. Da sind Case Statements auszuwerten, Unterprogramme aufzurufen usw. Das heisst, mit einem (reinen) RISC Prozessor verursachen wir wahrscheinlich viel mehr Wartezeit, da viel mehr Operationen auszufuehren sind, die man bei einem CISC in einem Schritt kodieren kann.Allerdings muß der Prozessor im Anschluß diese Befehle wieder dekodieren, um sie auszuführen. Auch wenn man bei RISC mehr Kram mit weniger Befehlen erledigen kann wird der Kram deswegen nicht wirklich schneller - es sei denn wir entwickeln den Prozessor wirklich nur als Grundlage einer VM, in welchem Fall wir den Instruktionssatz komplett auf einer höheren Ebene ansiedeln sollten.
Ich plane den Prozessor so, daß wir ihn rein theoretisch physikalisch umsetzen könnten. Werden wir wahrscheinlich nicht, aber ich sehe das Ganze hier als eine Art Planspiel.
Man koennte als die ganze Arbeit des CISC Befehles durch schon vorgefertigte betriebssystemnahe und optimiere Hochsprachenfunktionen ersetzen. Effektiv sollte das also schneller sein.
Ich wuerde also Vorschlagen, sich an der RISC Architektur mit ihren fixierten Befehlsbreiten und hohen Registerzahlen (teilweise ueber 256) zu orientieren, jedoch auch einen erweiterten CISC Befehlssatz mit komplexen Routinen anzubieten, die dann im Intgerpreter schnell und kompakt nativ durchgefuehrt werden koennen. Denn man sollte bedenken, in unserem Fall kann man einen CISC ohne Geschwindigkeitseinbusse als RISC betreiben, aber nicht umgekehrt.
Naja, ich strebe ja eben an, daß der Kram auch in vivo realisierbar ist; da wären derartige Specs eher hinderlich.
Das was Rolus und Jeez sagen, wiederspricht doch in keiner Weise dem, was ich gesagt habe. Ich habe nie gesagt, dass ein CISC keine einfachen RISC Befehle haben soll. Und die komplexen Funktionen sollen auch nichts bewirken, was mit normalen Prozessoren nicht ginge. Den obigen CPY Befehl gibt es (unter anderem Namen) bereits seit dem 286er Befehlssatz. Und da solche komplexen Funktionen effektiv umgesetzt werden koennten, wuerde sich das anbieten.
Auch die hohe Anzahl von Registern sollte aus technischer Sicht nicht das Problem darstellen. Es wurden schon RISC Prozessoren mit mehr als 256 registern in den 80ern gebaut und von Seiten der VM stellt eine hohe Registeranzahl keinen Mehraufwand gegenueber wenigen Registern dar, da die VM die Register in einem einfachen Datenarray verwalten kann.
Was den Programmieraufwand betrifft, so muessen wir in jedem Fall die mathematischen Routinen selber schreiben, wenn wir die Bitbreite und/oder das Encoding aendern. Selbst bei 32bit muessen wir wenn wir von little Endian auf BigEndian wechseln (wobei ich sagen muss letzteres ist besser lesbar, da wir ja auch von links nach rechts lesen, sollte das Least Significant Bit auch rechts stehen) die Arithmetik neu schreiben. Da kommen wir wohl kaum drum rum, ausser wir bauen einen x86 nach.
Das Problem der CISCs liegt ja darin, dass die Dekodierung der Befehle so lange lange dauert, weil ihre Laenge variabel ist, zu gunsten einer hohen Befehlsanzahl. Dieses Problem haben wir ja nicht wirklich, auch wenn wir mit unserem Prozessor realistisch halten wollen. Mit einer festen Befehlsstruktur haben wir genuegend Platz um die Befehle sehr flexibel zu halten. Wenn ein Befehl immer aus 96bit besteht, koennen wir alle besonderheiten gleich hineincodieren. Nehmen wir einfach mal an, unser Prozessor wuerde 2048 verschiedene Register haben (addressierbar ueber 12 bit). Das koennte z.B. in einem InVivo Prozessor durch einen weiteren addressierbaren First Level Cache realisiert werden (wie es in einigen RISC Prozessoren der Fall ist), der 384 kB gross waere. Dann koennte man die 96bit eines jeden Befehles in 8 Bloecke a 12bit unterteilen. Die ersten 12bit koennten zur Bezeichnung von bis zu 2048 Befehlen verwendet werden. Die anderen 7 Bloecke koennten zur Addressierung von bis zu 7 Registern, zur Spezifizierung des Datenformats (Register mit welcher Bitbreite interpretieren), zur Uebergabe von konstanten Daten oder aehnliches benutzen. Wenn zusaetzliche Daten oder Daten in voller 96bit Breite erforderlich sind, koennen immer noch weitere Daten zur Berarbeitung nachgeladen werden. Wenn ein Befehl also nicht die vommen 96bit braucht, wuerde einfach der Rest mit Nullen gepaddet werden. Zumindest wuerde es wohl ein In Vivo Prozessor so machen.
Jesus_666
12.04.2006, 23:08
Naja, mir geht es um Folgendes:
1.) Der erweiterte Befehlssatz wird oft nicht genutzt. Besonders Compiler neigen dazu, auf allen Plattformen RISC-Code zu produzieren.
2.) Mit CISC haben wir größeren Overhead durch Befehl <=> Mikrocode-Übersetzung und/oder aufwändigere Technik im Rechenwerk.
3.) Man könnte in der Tat mit RISC anfangen und später zusätzliche Instruktionen dranklatschen.
Ergo: Vorerst würde ein RISC-Prozessor wahscheinlich einfacher umzusetzen sein (und ja, ich weiß, daß die VM problemlos mit einem Prozessor klarkommen würde, der sogar Instruktionen für das Verarbeiten ganzer Strings bietet).
Jesus_666
14.04.2006, 11:24
Okay, veränderte Situation. Luki hat ja im Hauptthread klargestellt, um was es bei der Sache eigentlich geht. Ich formuliere meine Empfehlungen also neu.
Bittigkeit: 32. Wähend ich kein Problem mit 64bittigkeit hätte müßten wir für jeden mit IA-32-Prozessor Routinen schreiben, die die 64bittigen Berechnungen in 32bittige umwandeln. Mit einer 32bittigen Gastmaschine haben wir relativ geringen Implementationsaufwand bei relativ hoher Performanz.
Register: Völlig egal. Register sind bei uns nicht viel schneller als RAM, also ist es relativ egal, ob wir 32 oder 32768 davon haben. Zu viele Register könnten dazu führen, daß viele Register nie genutzt werden.
Befehlssatz: Wir haben durch einen riesengroßen Befehlssatz keine Nachteile, weil die unterste Ebene ultimativ sowieso C(++) sein wird, daher CISC.
Befehle: (Ich erhebe keinen Anspruch auf Vollständigkeit!)
Genereller Kram: NOP (tut nichts), INTER (Software Interrupt)
Arithmetik: ADD (Addition), SUB (Substraktion), MUL (Multiplikation), DIV (Division)
Boole'sche Logik: AND, OR, XOR, NOT
Branching: BEQ (Branch on equal), BNE (Branch on not equal), BGTZ (Branch on greater than zero), BLTZ (Branch on lesser than zero), BGEZ (Branch on greater than or equal to zero), BLEZ (Branch on less than or equal to zero)
Sprünge: J (Jump)
Speicherzugriffe: LOAD, STORE
Bitshifts: SLZ (Shift left, fill with zeroes), SRZ (Shift right, fill with zeroes), SLO (Shift left, fill with ones), SRO (Shift right, fill with ones), ROL (Rotate Left), ROR (Rotate Right)
zusätzliche CISC-Befehle
Byteordnung: Big-endian. Einziger Grund: Das Internet Protocol ist big-endian.
Darstellung von Fließkommazahlen: Als IEEE-Fließkommazahlen natürlich.
Multiprocessoring: Führt zusätzliche Komplexität ein, würde ich u.U. erst in einer späteren Version einbauen. Vielleicht könnte man von Anfang an mehrere Hauptbusse einplanen, an denen hinterher sowohl ein Prozessor als auch etwas anderes (ein Northbridge-Äquivalent) hänge könnte.
Interrupts: Geht es überhaupt ohne? Die Behandlung sollte wie bei anderen Prozessoren auch ablaufen: Stack sichern, Behandlungsroutine durchlaufen lassen, zurückspringen.
Ports: ...
Was die Bittigkeit angeht: Da können wir natürlich mit 96 arbeiten, ich rechne dann aber mit eher mäßiger Performanz und hohem Implementationsaufwand (riesige Mengen von LOAD- und STORE-Befehlen etc.).
Hm, bekackt.
Noch ein paar Befehle, die ich für nötig halte:
CMP Um Operanden zu vergleichen. Darauf kann man ein bedingter Sprung folgen.
IN/OUT Kommunikation mit Ports.
INC Inkrementiert den Operand.
DEC Dekrementiert den Operand.
Die sollten meiner Meinung nach unbedingt unterstützt werden. Eventuell noch Stackbefehle und Schleifenbefehle.
freundliche Grüße, Rolus
Ich Stimme Jeez und Rolus in Fragen der Befehle vollstaendig zu.
Zudem wuerde ich vorschlagen, dass es die Shift-Operationen sowohl in der klassischen als auch in einer 2 Registervariante geben sollte. In dieser Variante gehen die herausgeschobenen Bits nicht verloren, sondern werden vom zweiten Register als Least Significant Bits aufgedangen. Ein Beispiel (in 8bit):
MOV AX 10110011
SLZ 4 AX BX
; AX = 00110000
; BX = 00001011
MOV AX 10110011
SRZ 4 AX BX
; AX = 00001011
; BX = 00000011
Das koennte fuer schnelle Division mit Rest und fuer Kryptographie gut eingesetzt werden.
Was Jeez einspruch bezueglich der Registeranzahl angeht, denke ich, dass gerade Compiler davon profitieren koennten. Lokale Variablen in Funktionen koennten dann naemlich in den haeufigsten Faellen durch Register ersetzt werden. Gut, fuer unseren Fall waere das ganze praktisch unerheblich, da unsere "Register" auch im Ram liegen und somit praktisch gleichschnell sind. Fuer eine vermeintliche hypotetische reale Recheneinheit waere das allerdings ein grosser Vorteil.
@Jeez, was genau meinst du mit Branching ? Einfach die normalen bedingten Spruenge ? Ich kenne die bisher unter den Symbolen JZ (Jump if Zero), JNZ (Jump if not zero) usw .. also das Aequivalent zu dem, was du aufgefuehrt hast. Liege ich da richtig, oder meinst du mit Branching Prozessverzweigung wie mit dem Fork Befehl unter C ? Auch verstehe ich deinen Einwand mit den Unmengen an Load und Store befehlen nicht ganz. Koenntest du das bitte genauer ausfuehren ? Meinst du vielleicht, weil dann 1024 byte = 1KB nicht mehr in eine gerade Anzahl an Registern passen ? Immerhin koennten wir unser KB mit 1056 byte = 11 Word oder vielleicht zweckmaessiger mit 1KB = 960 byte = 10 Word definieren ... Im Grunde sind das doch auch nur willkuerlich definierte Werte
Jesus_666
18.04.2006, 12:09
1.) Ich denke, daß Intels JNZ etc. zu MIPS` BLTZ etc. äquivalent sind. Meine Liste habe ich aus der Befehlsliste für MIPS-Prozessoren konstruiert.
2.) MIPS als 32bittige Architektur weist drei LOAD/STORE-Befehle auf: Für 8 Bit, 16 Bit und 32 Bit. Weil man eben oft mit Bytes, Words und DWords arbeitet. Bei 96 Bit müßten wir entsprechend erweitern - oder wir schreiben vor, daß man grundsätzlich nur mit 96bittigen Werten arbeiten kann. Ich denke da an separate Befele für 8, 16, 32, 48, 64 und 96 Bit.
Da hast du natuerlich recht. Andererseits wuerde das Problem nicht so gravierend fuer den Decodierer im Prozessor ausfallen, wenn man definiert, dass ein Maschienencodebefehl immer 96bit breit ist (was zweckmaessig ist, da das ja die breite eines Registers ist) In 96 Bit kann man viele Informationen unterbringen. So koennte man beispielsweise mit "Maschinencodeparametern" arbeiten. Die ersten 16bit geben die Art des Befehls an, und die naechsten Bits spezifizieren dann, welche Register und welche Untereinheiten des Registers der Befehl verwenden soll. Wenn wir z.B. mit 4096 Registern arbeiten sollten, koennten wir diese mit 16bit codieren, wobei 12bit die Nummer des Registers angeben und 4 bit spezifizieren, welche Bytes des Registers angesprochen werden. Das gaebe sogar die Freiheit, z.B. die Bytes 2, 5, 6 und 9 aus dem 96bit Register konkateniert als 32bit Register zu behandeln, wofuer das auch immer noetig sein mag ...
Der Ansatz klingt nicht schlecht. Damit könnte man Problemlos je drei 32 Bit Register pro echtem Register emulieren und ein 64 Bit Datentyp (Long?) ließe sich auch problemlos unterbringen.
Grad beim Stöbern auf der Page von jemandem aus meiner Schule gefunden: http://dagugs.de/gfs.html. Ich hab das Worddokument nur kurz überflogen, aber vielleicht könnte uns das helfen.
Ich habs jetzt nicht einmal überflogen, aber ist das soetwas ähnliches wie http://mycpu.mikrocontroller.net/index2.htm ?
Nicht unbedingt. Das sieht nach Notizen für ein Referat (GFS = Gleichwertige Feststellung von Schülerleistungen = in BW vorgeschriebenes Referat als zusätzliche Klassenarbeit) aus. Der Inhalt selber ist soweit ich das gesehen hab recht oberflächlich, aber da sind einige Quellen angegeben, die hilfreich sein könnten.
Powered by vBulletin® Version 4.2.3 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.