Du befindest dich hier: FSI Informatik » Prüfungsfragen und Altklausuren » Hauptstudiumsprüfungen » Lehrstuhl 4 » Virtuelle Maschinen (7,5 ECTS)   (Übersicht)

Virtuelle Maschinen (7,5 ECTS)

Prüfer: Volkmar Sieh, Beisitzer: Bernhard Heinloth

Fragen

JVM

Was macht die JVM alles so?

  • keine Exceptions
  • keine Interrupts
  • keine Flag-Berechnung
  • sichere Pointer statt MMU
  • keine wirklichen berechneten Sprünge
  • kein selbst-modifizierender Code → ganzes Programm kann am Stück kompiliert werden (muss man aber nicht, weil vielleicht nicht der gesamte Code benötigt wird)
  • Laufzeitwissen nutzen für bessere Optimierungen

Hier habe ich mehrere Male etwas Hilfe gebraucht, d.h. Volkmar hat öfter kleine Fragen gestellt, um mich hinzuleiten.

Was ist die HotSpot-Optimierung?

Es gibt für jeden kompilierten Block einen Counter. Wenn der Counter einen hohen Wert erreicht, wird der Block nochmal kompiliert, und diesmal besser optimiert.

Wie macht man diesen Counter? Der braucht doch auch wieder Rechenzeit…?

Es ist nur eine Addition, und dieser kleine Aufwand lohnt sich (anscheinend), weil durch das Neukompilieren mit Optimierungen wohl genug Zeit eingespart wird.

Was macht man mit dem Counter, nachdem der Block neu kompiliert wurde?

Man kann den Counter einfach weglassen. Hierauf bin ich nicht gekommen.

Wie kann man schneller sein, als die JVM?

Hardware-basiert. Hier hätte man wahrscheinlich auch was Anderes sagen können, d.h. man konnte sich das Thema praktisch aussuchen.

Hardware-basierte Virtualisierung

Was ist die Idee dahinter?

Wenn man die gleiche CPU-Architektur emulieren will, wie mein PC hat, kann man unprivilegierte Befehle einfach direkt ausführen. Nur bei privilegierten Befehlen muss man eventuell „emulieren“.

Was wären denn solche privilegierten Befehle?

cli, sti, mov cr?, popf, sidt, sgdt, mov $memory-mapped-bla, in, out

Und wieso sind die problematisch?

  • cli/sti sollen nicht Interrupts beim Host beeinflussen
  • popf darf Interrupt-Flag nicht verändern Auf das konkrete Flag bin ich nicht sofort gekommen, auch hab ich hier fälschlicherweise was von pushf geredet, welches aber kein Problem ist.
  • mov cr? kann Schattenregister in VMCS verwenden → nicht schlimm
  • in/out/mov $memory-mapped-bla müssen meistens ganz emuliert werden
  • (man kann an sich alles konfigurieren, sodass z.B. bestimmte Interrupts kein exit-Event erzeugen)

Was ist denn Performance-mäßig besonders schlimm?

Page-Tabellen umschreiben. Das meinte er nicht, „könnte aber sein“.

I/O, vor allem Grafik.

Wie kann man Grafik dann machen? Da gab es drei Möglichkeiten…

  • mov-Instruktionen einfach zulassen, aber erst durch zweiten Thread den eigentlichen Bildschirm updaten
  • mov-Instrukionen auf Funktionsaufrufe abbilden
  • extra Grafik-Hardware mit speziellem Treiber definieren

Wie könnte so ein spezieller Treiber denn aussehen?

Man kann das Bild, z.B. in RGB-Form, einfach in einen normalen Speicherbereich schreiben. Dann übergibt man einen Pointer darauf an eine „Stelle diesen Speicher dar“-Instruktion. Dadurch hat man nur bei dieser einen Instruktion ein exit-Event.

Alternativ kann man auch Instruktionen haben wie „zeichne eine Box mit dieser Farbe/Größe“.

Wie sieht denn der Zustand aus, denn man bei Vanderpool sichern muss?

rsp, rip, rflags, cr?, Segmentregister (bei Gast mit hidden-Part, bei Host ohne)

Irgendwie hab ich auch erwähnt, dass das Umschalten relativ teuer ist.

Bibliotheks-basierte Virtualisierung

Wie funktioniert das?

Man baut nur die ABI nach.

Was beinhaltet das alles?

  • CPU-Instruktionen: die Instruktionen müssen ausgeführt werden können
  • Memory-Layout: es dürfen nicht Speicherbereiche verwendet werden, die vom Betriebssystem ausgehend nicht verwendet werden können
  • Library-Interface muss ersetzt werden
  • eventuell System-Calls

Wenn ein Programm SSE-Instruktionen hat, kann ein alter PC das Programm auch ausführen. Warum?

Weil die SSE-Instruktionen nicht ausgeführt werden. Das Programm prüft, ob die aktuelle CPU das unterstützt → wird nicht unterstützt → Fallback ohne SSE wird verwendet. Hierfür hab ich etwas gebraucht.

Muss ich jetzt alle Libraries ersetzen? Was sind dabei Probleme? Man muss nur eine Library ersetzen, durch die alle anderen „durchgehen“. Wenn bei Linux alles letztendlich über die libc geht, reicht es, die zu ersetzen.

Probleme sind, dass (v.a. Windows-Libraries) schwierig nachzumachen sind. Werden meistens reverse-engineert, wodurch Fehler enthalten sein können.

Wie ist das bei System-Calls?

Wenn sie statisch enthalten sind, braucht das Betriebssystem eine Personality, um die entsprechenden System-Calls zu unterstützen. Das muss man dem Betriebssystem dann auch mitteilen (z.B. mittels personality(2)).

Ein Programm sagt aber doch nicht „Ich bin ein Windows-Programm“…?

Man hat einen Loader (wie wine), welcher das macht.

Was macht ein Loader wie wine alles so?

Hier hab ich was bzgl. Libraries erzählt, dass der Mechanismus (d.h. mittels Procedure Linkage Table) derselbe sein muss, sonst wird es schwierig. Keine Ahnung, wie sinnvoll meine Antwort war, und ob er das hören wollte…

Anmerkungen

Ich hab öfter mal nicht gewusst, worauf er hinauswollte, oder ich habe länger überlegt. Er hat auch oft noch kleinere Fragen gestellt, teils um mir zu helfen, teils um noch Details zu wissen. Manche Fragen habe ich sicherlich vergessen.

Letztendlich war es aber nicht so schlimm, da Bernhard wohl auch teilweise nicht ganz wusste, worauf Volkmar hinaus wollte. Er hat dann noch gesagt, dass sie mich beide als guten Studenten kennen, und meine Abgaben gut waren, weswegen es dann bei der 1,0 geblieben ist. Keine Ahnung, ob ich mit schlechteren Abgaben wirklich eine schlechtere Note bekommen hätte.