JAVA-Prozessoren - weblearn.hs

Werbung
Rechnerstrukturen
Bericht zu dem Vortrag über Java-Prozessoren
Name: Matthias Pohl
Semester: E7EI
Mat.Nr.: 11382
Seite 1 von 15
Inhalt
1. Einleitung .................................
1.2 Javaspezifikationen .......................
1.3 Beispiele für Javaprozessoren .............
3
3
5
2. Details zum aj-100 ......................... 6
2.1 Prinzipielle Funktionsweise der JVM ....... 6
2.2 Aufbau des aj-100 ......................... 7
2.3 Echtzeiterweiterungen des aj-100 .......... 12
3. Anwendungsbeispiele / Fazit ............... 13
3.1 Quellen ................................... 15
Seite 2 von 15
1. Einleitung
Java ist zu einer bedeutenden Programmiersprache herangewachsen und
hat sich weitgehend etabliert. Doch neben vielen Vorteilen gibt es
auch einige Nachteile, die bei der Verwendung von Java vorhanden
sind. Einer der gewichtigsten dürfte sicher die Performance sein.
Da die Java-Virtual-Machine (JVM)[1] auf jedem Rechner emuliert
werden muss, entstehen durch diese Interpretierung des Bytecodes
enorme Leistungsverluste. Mittlerweile ist dies in dem Desktop PCBereich nicht mehr ein großes Problem, da die heute erhältlichen
Rechner Leistung im Überfluss mitbringen. Doch im Embedded-Bereich
und dort besonders im mobilen Sektor ist notwendig, aufgrund der
eingeschränkten Möglichkeiten, die durch notwendige
Stromsparmaßnahmen auftreten, andere Wege zu gehen.
Statt einer software-seitigen Übersetzung des Bytecodes werden CPU's
entwickelt, die diesen direkt verstehen können.
1.2 Javaspezifikationen
Bild 1.2.1: Java-Spezifikationen im Überblick[8]
Sun erkannte die Notwendigkeit von zusätzlichen Java-Spezifikationen
für Eingebettete Systeme und schuf zusätzlich zur Java2-StandardEdition die Untermengen CDC (Connected Device Configuration)und CLDC
(Connected Limited Device Configuration). Die CDC sowie CLDC werden
auch unter dem Begriff Java-Microedition (J2ME)[2] zusammengefasst.
Die Anforderungen der beiden Untermengen CDC und CLDC unterscheiden
sich im Wesentlichen in ihrem Speicherbedarf:
CDC: min. 256kB RAM und 512kB ROM
CLDC: 128kB-512kB Speicher (RAM und ROM)
CDC ist hauptsächlich für Settop-Boxen und stationäre Geräte
gedacht. Für CLDC ist zusätzlich der Batteriebetrieb für den mobilen
Einsatz spezifiziert.
Wie man aus Bild 2.1 erkennen kann ragen die Spezifikationen CDC und
CLDC etwas aus der J2SE heraus. Dieser Teil sieht zusätzliche
Möglichkeiten wie direkte Hardwarezugriffe und spezielle GrafikFunktionen für kleine LCD-Displays vor.
Seite 3 von 15
Bild 1.2.2: Einsparungen bei der J2ME am Beispiel der CLDC
Einsparungen bei der J2ME sind z.B. :
-
Wegfall der JNI
keine Mechanismen zur Klassenverifizierung
keine Objektfinalisierung durch den Garbage-collector
teilweise Wegfall von einigen Grunddatentypen aufgrund
fehlender FPU's in mobilen Prozessoren
weitere Einsparungen in java.net, java.io und java.util
Geändert wurden:
-
die AWT-Klassen
Klassen für Netzwerkanbindungen (Generic Connection Framework)
sowie Klassen für Datenbankzugriffe (Record Management System)
Diese neuen Funktionen werden unter einem neuen Namespace
(java.microediton) zusammengefasst.
Seite 4 von 15
1.3 Beispiele für Javaprozessoren
Tabelle 1.3.1 Zeigt eine kleine Auswahl der derzeitig erhältlichen
Javaprozessoren.
Produkt
Hersteller
Sprache(n)
aj-100
Jazelle
MB86799
JSTAR
Lightfoot
picojava-2
aJile
ARM
Fujitsu
Nazomi
DCTL
Sun
native Java
Multi Language
Native Java(Picojava2)[3]
native Java
Multi Language
native Java
Tabelle 1.3.1: Javaprozessoren am Markt
Die letzten drei Produkte sind dabei nur CPU-Core-Spezifikationen,
die CPU-Hersteller einkaufen können, um ihren eigenen CPU's JavaFunktionalität hinzuzufügen, so wie offensichtlich Fujitsu dies
getan hat.
Die Begriffe in der Spalte Sprache(n) sind so zu verstehen:
Native Java:
kann ausschließlich nativen Bytecode verstehen
Multi Language: kann Bytecode und zusätzlich eigene Mnemonics
verstehen, Beispiel ARM Jazelle (dieser versteht
neben seinem nativen Risc-Befehlssatz zusätzlich
Java-bytecode).
Multi-language-Prozessoren sollen die Akzeptanz bei den Entwicklern
im Embedded-Bereich fördern, da von diesen die Programmiersprache
'C' immer noch weitgehend bevorzugt wird.
Zum Leistungsvergleich der erhältlichen Prozessoren wird
gebräuchlicherweise ein Benchmark der Firma 'Pendragon Software
Corporation' namens "Embedded CaffeineMark 3.0"[14] herangezogen.
Name
Mhz
CaffeineMarks/Mhz
mW/Mhz
aJile aj-100
100
2,75
<1
Fujitsu MB86799
66
9,4
5,4
ARM Jazelle
200
5
0,45
Tabelle 1.3.2: Ergebnisse des Embedded CaffeineMark 3.0
Bei diesem Benchmark werden fünf Tests durchgeführt:
- Sieb des Eratosthenes (Algorithmus zum finden von Primzahlen)
- Logiktest (prüft Geschwindigkeit von bedingten Sprüngen)
- Schleifendurchlauftest (Sortieraufgaben und Sequenzgenerierung)
- Methodenaufrufe (rekursive Methodenaufrufe)
- Float (simuliert 3d-rotation eines Objektes um einen Punkt)
Je öfter die Tests in einer vorgegebenen Zeit durchlaufen werden
können, desto höher die Zahl der CaffeineMarks. Zum Schluss werden
alle Einzelergebnisse zu einem Gesamtwert zusammengefasst. Die, in
der Tabelle aufgeführten, Ergebnisse (entnommen aus dem Artikel
"Silicon variety vanquishes embedded-Java taboos"[6]) sind also
somit mit Vorsicht zu genießen.
Seite 5 von 15
Um eine Standardisierung der Benchmarks in diesem Bereich zu
erreichen hat sich das "Embedded Microprocessor Benchmark
Consortium" oder kurz: "EEMBC" zusammengefunden. Die, mehr als 40
Mitglieder aus der Chip-Industrie und Compiler-Hersteller, die
dieser Organisation angehören, haben sich das Ziel gesetzt,
bestehende Benchmarks zu prüfen und zu zertifizieren. In Zukunft
sollen selber Standard-Benchmarks entwickelt werden, die nicht so
leicht durch bestimmte Compileroptimierungen oder ähnliches
ausgetrickst werden können und mehr Typische Alltagsszenarien
beinhalten.
2. Details zum aj-100
In diesem Bericht wird nun exemplarisch der aj-100 von aJile[4]
näher erläutert.
2.1 Prinzipielle Funktionsweise der JVM
Vorweg eine Bemerkung zur prinzipiellen Funktionsweise der JVM.
Diese ist ein Stackbasierter Prozessor. Den Unterschied zum
bekannten registerbasierten Prozessor soll folgendes Beispiel
klären:
Registerbasierte Addition
Stackbasierte Addition (JVM)
ADD R3, R2, R1
ILOAD_1
ILOAD_2
IADD
ISTORE_3
Bei der registerbasierten Addition werden die Register R1 und R2
direkt addiert und in R3 gespeichert.
Im Gegensatz dazu werden die beiden Operanden bei der stackbasierten
Addition erst von den lokalen Variablen aus auf den Stack geschoben
(iload_1 , iload_2) und dann mit iadd addiert.
Bei jedem Methodenaufruf wird ein Array für die lokalen Variablen
der Methode auf den Stack gelegt.
Die lokalen Variablen können dann mit den entsprechenden Anweisungen
geladen (ILOAD_n) bzw. gespeichert (ISTORE_n) werden. 'n' gibt
hierbei den Offset in dem Array der lokalen Variablen an.
Die parameterlose Additionsoperation kann die Operanden in den
lokalen Variablen also nicht direkt benutzten, da immer nur die
obersten beiden Operanden vom Stack genommen, addiert und das
Ergebnis wieder oben auf den Stack gespeichert wird.
Von dort verfrachtet der letzte Befehl, istore_3, das Ergebnis in
die lokale Variable Nummer 3.
Seite 6 von 15
2.2 Aufbau des aj-100
Der aj-100 ist eigentlich mehr ein Mikrocontroller als nur eine CPU.
Er bietet diverse zusätzliche Hardwareeinheiten wie UARTschnittstellen, Timer, einige General-purpose-Schnittstellen sowie
zahlreiche Funktionen für Echtzeitfunktionalitäten.
Gerade diese Echtzeitunterstützung ist im Embedded-Bereich ein
willkommenes Feature, da kein Echtzeitbetriebsystem mehr benötigt
wird.
Diese Erweiterung des Befehlssatzes ist problemlos möglich, da für
den Opcode 8Bit vorgesehen aber, laut Spezifikation, nur ca. 230
Befehle vorhanden sind.
Der aj-100 sieht auch vor, eigene Befehle als Micro-code in das
eingebaute RAM laden zu können. Somit kann z.B. eine häufig benutzte
Java-Methode wie java.lang.Math.sqrt() als Opcode integriert werden.
Der Compiler versucht in der Regel, zeitaufwendige Anweisungen
automatisch durch Micro-code zu ersetzen.
Neben dem aj-100 existiert noch der aj-80[5] aus derselben Reihe.
Dies ist im Prinzip nur eine abgespeckte Version des aj-100, der mit
einem 8Bit-breiten statt einem 32Bit-Datenbus an externen Speicher
angeschlossen ist, sowie nur bis 80Mhz getaktet werden kann. Der
aj-100 kann im Gegensatz dazu bis 100Mhz getaktet werden.
Der aj-100 basiert, wie auch der aj-80, auf dem JEM2-Core, der von
Rockwell-Collins entwickelt wurde. Bereits Mitte der 90er-Jahre
hatte Rockwell-Collins den JEM1 fertig entwickelt aber nie
veröffentlicht, da die Funktionalität nicht so gut für EchtzeitApplikationen geeignet war.
Der JEM2-core wurde exklusiv von der Firma aJile lizenziert. Da die
JVM stackbasiert ist, wählte man bei der Entwicklung ebenfalls einen
stabasierten Ansatz.
Der aj-100 beherrscht bis auf zwei, alle Bytecodes. Die fehlenden
beiden sind aThrow (Exception werfen) und multianewarray
(multidimensionales Array anlegen).
Diese beiden Befehle wurden aufgrund ihrer nicht deterministischen
Natur (bezogen auf die Ausführungszeit) nicht integriert, da dies
die Echtzeitfunktionalität nicht mehr voll gewährleisten würde.
Stattdessen werden diese Befehle, falls sie dennoch benötigt werden,
über Traps an Software weitergeleitet.
Bei den ARM Jazelle-CPU's hingegen, werden nur ca. 140 Opcodes in
Hardware realisiert und der Rest (ca. 94 Opcodes) müssen in Software
nachgebildet werden.
Seite 7 von 15
Bild 2.2.1: Blockschaltbild des aj-100
In dem Blockschaltbild des aj-100 kann man im unteren Bereich links
einige Serielle Schnittstellen erkennen. Neben den Standard UARTSchnittstellen gibt es noch ein Serial Peripheral Interface, welches
zum Anschluss von beispielsweise A/D-Wandlern dient.
Auf der rechten unteren Seite sind einige Timer für generellen
Einsatz zu erkennen, die nicht von den eingebauten
Echtzeitfunktionen belegt sind. Alle diese Komponenten sind über
einen Peripherial Bus mittels einer Bridge an den Prozessorbus
angeschlossen.
Oben rechts sieht man die JTAG-Schnittstelle, welche zum
programmieren und testen des Systems dient. Darauf folgt der JEM2Core, der weiter unten erläutert wird.
Die 16kByte RAM sind für die bereits erwähnten eigenen Opcodes
vorgesehen, die als Micro-Code dort abgelegt werden. Außerdem
befindet sich dort noch der Kernel für die Verwaltung der
Echzeitfunktionen sowie Einstellungen für die Kontrolle mehrerer
JVM's.
Die folgenden 32kByte RAM sind für den Stack vorgesehen, da die
JEM2, wie erwähnt, ein Stackbasiertes Design hat.
Rechts daneben ist der Schaltkreis für die Kontrolle von mehreren
JVM's zu sehen.
Dieser ermöglicht die Existenz von zwei JVM's gleichzeitig.
Seite 8 von 15
Bild 2.2.2: Multiple JVM Controller (MJM)
Dabei wird Zeitscheibenbasiert (timesliced) zwischen beiden JVM's
umgeschaltet.
Dabei hat jede JVM ihren eigenen Thread Manager, ihre eigenen Timer
sowie eigens zugewiesene Interrupts (im ganzen System sind über 30
vorhanden). Somit verliert keine der Beiden JVM's ihre EchtzeitFähigkeiten.
Ebenso kann eine Memory-Protection vorgesehen und konfiguriert
werden. Dabei wird in der MJM festgelegt auf welche Speicherbereiche
des linearen Speichers, welche JVM exklusiv zugreifen darf.
Der restliche Speicher kann global alloziert werden und ermöglicht
somit eine Kommunikation zwischen beiden JVM's über Semaphoren.
Eine Kommunikation ist zusätzlich über die Standard Java-NetworkingAPI möglich.
Seite 9 von 15
Bild 2.2.2: Blockschaltbild des JEM2-Cores (Quelle: [4])
Bild 2.2.2 zeigt ein Blockschaltbild des JEM2-Cores. Deutlich kann
man die typischen Merkmale eines einfachen Prozessors erkennen.
Der Prozessorbus transportiert die zu dekodierenden Anweisungen.
Dabei wird der Opcode im Instruction-Register abgelegt. Wenn die
aktuelle Anweisung im Parser abgearbeitet worden ist, gelangt die
neue Anweisung in den Parser, der nun mit Hilfe des Micro-codeControl-Stores und dem MicroPC (Micro-Instruction-Programmcounter)
die Microinstructions erzeugt, im Microinstruction-Register ablegt,
ausführt und somit den Aktuellen Befehl im Parser Schritt für
Schritt abarbeitet.
Eventuelle Daten (z.B. aus lokalen Variablen) werden in das DataRegister geladen und stehen somit für Berechnungen zur Verfügung.
Dafür ist eine 32bit-ALU mit einem Schieberegister vorhanden.
Der Micro-code-Control-Store ist in 2 Bereiche unterteilt. Der eine
ist als ROM realisiert und beinhaltet alle Standard Bytecodes, die
Floating Point Funktionalität sowie die Debugger-Control, also die
Steuerung für die JTAG-Schnittstelle. Der andere Bereich ist
vorgesehen für den Echzeit-Kernel, die Steuerung des MJM (Multiple
JVM Controller) sowie der Speicherung des Microcodes, der
Selbstdefinierten Opcodes.
Auffällig ist das Registerfile, welches aus 24 32Bit-Registern
besteht. Dies mag bei einer stackbasierten CPU seltsam erscheinen
und leider werden über die art der Verwendung keinerlei Angaben
gemacht. Vermutlich werden diese Register aber dazu genutzt, den
oberen Teil des Stacks, ähnlich einem Cache-Speicher, zu halten.
Seite 10 von 15
Dies ermöglicht erhebliche Performancevorteile, sowie zusätzliche
Techniken, wie Instruction-Folding.
Bild 2.2.3: Funktionsweise des Instruction-Folding
Im Bild 2.2.3 ist das Ablaufschema des sogenannten InstructionFolding zu sehen, so wie es auch fester Bestandteil des PicojavaCore ist. Wie bereits in Kapitel 2.1 erwähnt wird bei jedem
Methodenaufruf ein Array für die lokalen Variablen der Methode auf
dem Stack abgelegt. Dieser Bereich liegt in dem Bild unterhalb der
etwas dickeren schwarzen Linie. Oberhalb beginnt der Stack für die
Methode, welcher nach oben wächst.
Normalerweise läuft eine Addition in der stackbasierten Java-Welt
wie im oberen Teil des Bildes ab.
Die beiden zu addierenden Variablen werden nacheinander auf den
Stack geschoben, die Anweisung iadd nimmt die obersten beiden
Operanden vom Stack, addiert diese und legt das Ergebnis wiederum
oben auf den Stack.
Danach nimmt die Anweisung istore_3 das Ergebnis vom Stack und
speichert es in einer lokalen Variablen. Diese Vorgehensweise
benötigt ganze 4 Takte.
Mittels Instruction-Folding, wie im unteren Teil des Bildes zu
erkennen, ist es möglich, diese Operation in einem 'Rutsch' (1 Takt)
durchzuführen. Dazu muss die CPU allerdings eine solche Abfolge von
Befehlen erkennen, um sie anschließend zu einem Befehl
zusammenfassen zu können. Dabei werden wie bei einer
registerbasierten CPU die Lokalen Variablen direkt geladen,
verarbeitet und gespeichert.
Seite 11 von 15
2.3 Echtzeiterweiterungen des aj-100
Der aj-100 bietet einige zusätzliche Befehle für
Echtzeitfunktionalität, die ein Echtzeitbetriebssystem weitgehend
überflüssig machen, welches nur zusätzlich Speicher belegen würde.
So sind z.B. einige Befehle für Threads in Micro-Code gefasst.
Als Beispiele sind zu nennen:
-
yield()
gibt laufwilligen Threads eine Chance, zu starten. (Falls
keine Threads an den Startlöchern stehen, fährt der Thread, der
yield() erteilt hat, einfach fort.)
Diese Funktion ist in der aj-100 besonders schnell gelöst und
benötigt nur ca. 300 ns.
-
join()
Wird sie an einen Thread geschickt, bedeutet das: Der aktuelle
Thread ist bereit, ewig zu warten, bis der benachrichtigte
Thread mit seiner run()-Methode fertig ist.
-
wait()
(und ihre zwei Varianten mit einem Timeout) veranlassen den
aktiven Thread, so lange zu warten, bis eine Bedingung erfüllt
ist. Die Methode notify() (bzw. notifyAll()), die innerhalb
einer synchronized-Methode aufgerufen werden muß, weckt
den aktiven bzw. alle Threads auf,
-
synchronized
Das Schlüsselwort synchronized fordert Java auf, den Codeblock
atomar durchzuführen. D.h. das dieser Codeblock von keinem
anderen Thread unterbrochen werden darf.
Somit lässt sich voraussagen, wie viel Zeit einzelne Threads in Java
für die Ausführung benötigen. Dies ist eine wichtige Voraussetzung
für die Entwicklung von Echtzeit-Schedulern.
Eine weitere problematische Sache für Echtzeitsysteme ist der
Garbage-Collector. Bei aJile hat man sich für einen einfachen
Standard mark-and-sweep Garbage-Collector als Softwarelösung
entschieden.
Bei diesem Verfahren (mark-and-sweep) wird der Speicher periodisch
nach Objekten durchsucht, die von laufenden Programmen aus noch
erreicht werden können. Die so gefundenen Objekte werden markiert.
Wenn alle erreichbaren Objekte markiert wurden, kann vom restlichen
Speicher – in dem wahrscheinlich noch einige nicht erreichbare
Objekte sind – angenommen werden, dass dieser frei ist.
Der Garbage Collector geht dann den Speicher durch, merkt sich
sämtlichen freien Speicher und fügt ihn wieder zum "freien
Speicherpool" hinzu.
Das 'mark-and-sweep'-Verfahren ist normalerweise nicht das Optimum
für Echtzeitanwendungen. Verfahren wie 'Generational Garbage
Collection' (GGC), die einen speziellen Speicherbereich für
kurzlebige Objekte vorsehen, welcher öfter gescannt wird, sind
Seite 12 von 15
besser geeignet. Bei dem aj-100 wird aber ein anderer Trick
angewandt.
Der Garbage-collector im aj-100 ist als synchronized Thread
implementiert, um sicher zu stellen, dass der Heap, der gerade
durchforstet wird, nicht in einen inkonsistenten Zustand gerät.
Weiterhin kann ein Bereich des Heap's von einem Thread alloziert
werden der nicht vom Garbage-Collector durchforstet wird. Dadurch
kann der Garbage-Collector sehr schnell von einem solchen Thread
unterbrochen (preempted) werden um diesen möglichen Echtzeit-Thread
ausführen zu können, der natürlich nur auf seinen eigenen Speicher,
der nicht vom Garbage-Collector bearbeitet wird, zugreifen darf.
3. Anwendungsbeispiele / Fazit
Der Einsatz von Javaprozessoren wird auf dem Mobilen Markt in
Zukunft sicher zunehmen. Gerade auch in Mobilfunktelefonen neuerer
Generationen finden bereits jetzt Java-Anwendungen. Zusätzliche
Echtzeitfunktionen werden viele Anwendungen im Embedded-Bereich
besonders bei Regelung- und Steuerungsaufgaben gut unterstützen.
Systronix Jstamp [7]
Der JStamp ist eine kleine Mikro-Controllerplatine, welche neben dem
zentralen aj-80-Microcontroller noch einen Spannungsregler sowie
512kByte SRAM und 512kByte Flash-Speicher beinhaltet.
Dieser Controller ist besonders für Regelungs- und Steuertechnik gut
geeignet. Dort kann er aufgrund seiner sehr kompakten Maße z.B. in
Robotern eingesetzt werden.
Seite 13 von 15
aJile aj-WRP100
Der aj-WRP100 ähnelt in seiner Funktionalität dem Handspring-PDA.
Neben normalen Funktionen eines PDA's kann das Gerät ebenso als GSMMobilfunktelefon genutzt werden, hat einen mp3-Decoder onboard,
beherbergt Email-Client, Webbrowser, hat diverse Schnittstellen wie
USB, ein Grosses Farbdisplay (240*320), 8MB Flash-ROM und 8MB SRAM.
Seite 14 von 15
3.1 Quellen/Referenzen
-
[1]"The JavaTM Virtual Machine Specification, Second Edition",
Sun Microsystems, Inc., http://java.sun.com/docs/books/vmspec/
-
[2]"JavaTM 2 Platform, Micro Edition (J2ME TM) Documentation",
Sun Microsystems, Inc., http://java.sun.com/j2me/docs/
-
[3]"PicoJava II Datasheet", Sun Microsystems,
http://solutions.sun.com/embedded/databook/pdf/datasheets/8054634-02.pdf
-
[4]"aJ-100 ReferenceManual v2.1", aJile, 06.12.2002
www.ajile.com/downloads/aJ-100ReferenceManual.pdf
-
[5]"aJ-80 Datasheet, aJile", 04.09.2001,
www.ajile.com/downloads/aJ-80Datasheet.pdf
-
[6]"Silicon variety vanquishes embedded-Java taboos",
EDN Access, 01.02.2001,
www.einsite.net/esec/Article_61880.htm
-
[7]JStamp, Systronix, www.jstamp.com
-
[8]"Low-Power Direct-Execution JavaTM Microprocessors for RealTime and Networked Embedded Applications", David S. Hardin,
http://java.isavvix.com/whitepapers/1014166430514.pdf
-
[9]"Java™ 2 Platform, Micro Edition: Connected Device
Configuration and Foundation Profile", Hinkmond Wong, David
Hardin, Kimmo Loytana, JavaOne 2001,
http://java.sun.com/javaone/javaone2001/pdfs/1602.pdf
-
[10]"Secure Reconfigurable Computing", Dr. David W. Jensen,
10.10.1999,
http://klabs.org/richcontent/MAPLDCon99/Presentations/F3_Jensen
_S.ppt
-
[11]"Hardware Accelerated Java™ Technology", Takashi Aoki,
Takeshi Eto, JavaOne 2001,
http://java.sun.com/javaone/jp2001/pdfs/549.pdf
-
[12]"ARM (Advance RISC Machine)", Pitipund Lorchirachoonkul,
Uchot Jitpaisarnsook,
http://www.cpe.ku.ac.th/~pom/courses/204521/report/2001/Jazelle
.ppt
-
[13]"Jazelle Whitepaper", ARM (Advance RISC Machine),
http://www.arm.com/arm/documentation?OpenDocument
-
[14] Embedded CaffeineMark 3.0, Pendragon Software, 1997,
http://www-sor.inria.fr/~java/tools/cmkit/info.html
Seite 15 von 15
Herunterladen