-
TECHNISCHES GEBIET
-
Die vorliegende Erfindung betrifft allgemein die digitale Datenverarbeitung und insbesondere die dynamische Optimierung von Computerprogrammiercode.
-
HINTERGRUND
-
In der letzten Hälfte des zwanzigsten Jahrhunderts begann ein Phänomen, das unter dem Begriff „Informationsrevolution“ bekannt ist. Obwohl die Informationsrevolution eine historische Entwicklung ist, die in einem größeren Rahmen als nur in Form eines beliebigen Ereignisses oder einer beliebigen Maschine verläuft, symbolisiert keine einzelne Einheit die informationelle Revolution besser als der digitale elektronische Computer. Die Entwicklung von Computersystemen ist sicherlich eine Revolution. Jedes Jahr wachsen Computersysteme schneller, speichern mehr Daten und stellen ihren Benutzern mehr Anwendungen bereit.
-
Im Kernstück eines Computersystems befinden sich eine oder mehrere zentrale Verarbeitungseinheiten (Central Processing Units, CPUs), die auch als „Prozessoren“ bezeichnet werden und Anweisungen ausführen, die im Speicher des Computers gespeichert sind. Vom Standpunkt der Hardware des Computers aus betrachtet arbeiten die meisten Systeme im Grunde genommen in derselben Weise. Prozessoren können eine festgelegte Menge sehr einfacher Operationen durchführen, zum Beispiel arithmetische und logische Vergleiche sowie die Bewegung von Daten von einem Ort zu einem anderen. Aber jede Operation wird sehr schnell durchgeführt. Computerprogrammcode auf verschiedenen Ebenen weist den Computer an, eine große Anzahl dieser einfachen Operationen durchzuführen, wodurch der Computer in die Lage versetzt wird, komplexe Aufgaben durchzuführen. Obwohl die festgelegte Menge einfacher Operationen begrenzt ist, sind die möglichen Abfolge und Kombinationen derartiger Operationen praktisch unbegrenzt, die im Programmcode angegeben werden können.
-
In der Anfangsgeschichte des Digitalcomputers wurden Computerprogramme, mit denen der Computer angewiesen wurde, eine bestimmte Aufgabe durchzuführen, in einer durch den Prozessor des Computers direkt ausführbaren Form geschrieben. Derartige Programme zu schreiben, zu verstehen und zu pflegen war für den Menschen sehr schwer, selbst wenn die Programme relativ einfache Aufgaben durchführen sollten. Da die Anzahl und Komplexität derartiger Programme zunahmen, wurde dieses Verfahren eindeutig undurchführbar. Zur Erleichterung der Entwicklung von Computerprogrammen wurde eine große Anzahl verschiedenartiger Sprachen entwickelt, um die Schaffung von Computerprogrammcode zu vereinfachen.
-
Höhere Sprachen unterscheiden sich in ihren Eigenschaften, aber alle diese Sprachen haben zum Ziel, einem Menschen das Schreiben eines Programms zur Durchführung einer bestimmten Aufgabe zu erleichtern. In der Regel stellen höhere Sprachen Operationen, feste Werte, Variablen und andere Konstrukte dar, die anders als für den Computer für den Programmierer leicht verständlich sind. Derartige Programme sind durch den Prozessor des Computers nicht direkt ausführbar. Um auf dem Computer ausgeführt werden zu können, müssen die Programme zunächst aus einer für den Menschen lesbaren Form (Quellcode) in eine durch den Prozessor eines Computers ausführbare Form umgewandelt werden, d.h. in eine Abfolge von Anweisungen, die durch den Computer direkt lesbar und ausführbar sind.
-
Eine Anweisung, die durch den Prozessor direkt lesbar und ausführbar ist (eine durch den Prozessor ausführbare Anweisung), ist eine Abfolge binärer Bits in einem vorgegebenen Format, wobei jede Bitposition speziell auf die Logik innerhalb des Prozessors zugeschnitten ist, der sie liest und decodiert. Kombinationen von Bitwerten geben eine Operation oder Operationen an, die durchgeführt werden soll bzw. sollen, eine Quelle oder ein Ziel von Daten, Verzweigungsbedingungen oder Verzweigungsziele und so weiter an. Die Formatierung der Bitfolge und die Bedeutung der Bitkombinationen legen den „Anweisungssatz“ des Prozessors fest. Obwohl die begrenzte Menge der von einem beliebigen Prozessor durchgeführten einfachen Operationen der anderer Prozessoren ähnelt, ist dies beim Anweisungssatz jedes Prozessors (d.h. das vorgegebene Format und die Bedeutung der binären Bitfolge der durch den Prozessor ausführbaren Anweisung) nicht der Fall.
-
Normalerweise ist der Quellcode allgemeingültig und für jeden verständlich, der in der Verwendung der betreffenden Sprache geübt ist, während ausführbarer Code speziell für eine bestimmte Computersystemumgebung vorgesehen ist und nur auf diesem Computersystem oder einem ähnlich konfigurierten Computersystem ausgeführt werden kann. Insbesondere ist der ausführbare Code speziell auf den Anweisungssatz des Prozessors zugeschnitten, obwohl er auch speziell auf andere Parameter des Computersystems zugeschnitten sein kann.
-
Um den in einer höheren Sprache vorliegenden Quellcode in durch den Prozessor ausführbare Anweisungen im Anweisungssatz des Prozessors umzuwandeln, existieren verschiedene Methoden. Quellcode kann „interpretiert“ werden, d.h., ein spezielles Programm (ein „Interpreter“) nimmt nacheinander jede Quellcodeanweisung und führt eine kleine Prozedur (d.h. eine Reihe von Anweisungen im durch den Prozessor ausführbaren Anweisungssatz) aus, die jeder Quellcodeanweisung entspricht. Das Interpretieren ist für manche Zwecke nützlich, aber generell nicht sehr leistungsfähig.
-
Bisher werden zur Erhöhung der Leistungsfähigkeit bei der Ausführung einzelne Teile (Module) des Quellcodes kompiliert, um Module aus durch den Prozessor ausführbaren Anweisungen zu bilden, die miteinander verknüpft werden können, um größere Programme zu bilden (obwohl einige Programme nur ein einziges kompiliertes Modul enthalten). Diese Programme werden in ausführbarer Form auf digitalen Datenträgern gespeichert und können in dieser Form auf andere Computersysteme verteilt werden oder auf dem System verbleiben, auf dem sie zuerst kompiliert wurden. In dieser Form werden sie später ausgeführt, üblicherweise viele Male. Die Kompilierung selbst ist eine Aufgabe, die von einem speziellen Computerprogramm (einem Compiler) durchgeführt wird und eine erhebliche Zeit in Anspruch nehmen kann. Oftmals gehören zur Kompilierung bestimmte Optimierungen am ausführbaren Code, die die Analyse der verschiedenen Anweisungsabfolgen innerhalb des Programms erfordern. Im Unterschied zu interpretiertem Code entsprechen in einem kompilierten Modul die entstandenen, durch den Prozessor ausführbaren Anwendungen nicht zwangsläufig bestimmten Quellanweisungen und folgen nicht zwangsläufig derselben Reihenfolge, obwohl sie dieselbe logische Ausgabe erzeugen müssen. Da erwartet wird, dass derartige Programme viele Male ausgeführt werden, wird die Kompilierungslast über viele Ausführungen hinweg verteilt. Die herkömmliche Form der Kompilierung wird manchmal als „statische Kompilierung“ bezeichnet.
-
In den letzten Jahren nimmt das Interesse an einer dynamischen „Just-In-Time“-Kompilierung oder „Just-In-Time“-Optimierung zu. Wie bei der statischen Kompilierung werden auch bei der „Just-In-Time“-Kompilierung/Optimierung oder dynamischen Kompilierung/Optimierung durch den Prozessor ausführbare optimierte Anweisungen erzeugt. Aber im Unterschied zur statischen Kompilierung werden die durch den Prozessor ausführbaren Anweisungen des Programms während oder als Teil der Ausführung des Programms erzeugt, dessen Teil die durch den Prozessor ausführbaren Anweisungen sind (das „Zielprogramm“). Das bedeutet praktisch, dass die Just-In-Time-Kompilierung/Optimierung oder dynamische Kompilierung/Optimierung darauf gerichtet ist, viele Male durchgeführt zu werden, zum Beispiel jedes Mal, wenn das Programm ausgeführt wird oder bei jedem Benutzerprozess, der das Programm ausführt.
-
Im Vergleich zur herkömmlichen statischen Kompilierung leidet die dynamische Kompilierung/Optimierung offensichtlich unter dem Nachteil, dass sie bei jeder Programmausführung oder bei jedem neuen Benutzerprozess durchgeführt wird. Mit der Just-In-Time-Kompilierung/Optimierung oder dynamischen Kompilierung/Optimierung sind jedoch verschiedene Vorteile verbunden, durch die sie bei vielen Umständen interessant wird. Beispielsweise wird dynamisch kompilierter Code auf dem System erzeugt, das ihn ausführt, und kann aus Code einer allgemeingültigen Zwischenform (zwischen einer höheren Quellsprache und einer durch den Prozessor ausführbaren Form) erzeugt werden, wodurch die Übertragbarkeit des Programms erleichtert wird. Ein derartiger Ansatz wird häufig bei der allgemein bekannten Umgebung der virtuellen JAVA(TM)-Maschinen verwendet. Des Weiteren ermöglichen zusätzliche Informationen, die dem System zur Ausführungszeit zur Verfügung stehen, wie zum Beispiel die exakte Systemkonfiguration, die gerade verwendeten Codemodule und das tatsächliche Muster der Codeausführung, die Erzeugung von effizienterem kompiliertem Code als normalerweise unter Verwendung eines statischen Compilers erzeugt werden kann. Derartige zusätzliche Informationen sind besonders wirksam im Falle von Mustern der tatsächlichen Codeverwendung, die es der dynamischen Kompilierung/Optimierung ermöglichen, sich auf die Optimierung bestimmter Teile des Codes zu konzentrieren.
-
Eine Form der dynamischen Kompilierung besteht darin, zur Ausführungszeit aus früher kompiliertem ausführbarem Code durch den Prozessor ausführbare Anweisungen zu erzeugen, im Allgemeinen ohne die Verwendung des ursprünglichen Quellcodes. Dies ist unter dem Begriff „dynamische binäre Optimierung“ bekannt. Die dynamische binäre Optimierung wird üblicherweise verwendet, um ein Computersystem zu emulieren, das eine andere, oftmals ältere, Architektur des Anweisungssatzes aufweist. Das heißt, dass ein ausführbares Computerprogramm, das früher kompiliert wurde und durch den Prozessor ausführbare Anweisungen in einer älteren Architektur des Anweisungssatzes enthält, aus dem zuvor kompilierten ausführbaren Code erneut kompiliert werden kann, um durch den Prozessor ausführbare Anweisungen im Anweisungssatz des aktuellen Prozessors zu erzeugen.
-
Obwohl die dynamische binäre Optimierung üblicherweise zur Unterstützung der Emulation verwendet wird, weist sie Möglichkeiten zur Verbesserung der Leistungsfähigkeit der Ausführung auf, selbst wenn der ursprünglich kompilierte ausführbare Code in dieselbe Architektur des Anweisungssatzes wie die des aktuellen Prozessors kompiliert wird. Anders ausgedrückt kann die Leistungsfähigkeit der Ausführung, die mithilfe der dynamischen Optimierung möglich ist, unter bestimmten Umständen den Zusatzaufwand der dynamischen Neukompilierung des bereits kompilierten Codes rechtfertigen, selbst wenn die früher kompilierte Version des Programms ohne weitere Kompilierung, Optimierung oder Umsetzung vollständig auf dem aktuellen Prozessor ausgeführt werden kann. In einigen Fällen kann diese Leistungsfähigkeit der Ausführung erhöht werden, wenn die Architektur des Anwendungssatzes um neue Funktionen erweitert worden ist, die vom ursprünglichen, statisch kompilierten Code (der sehr alt sein kann) nicht genutzt werden. In der Regel werden nur ausgewählte Teile des früher kompilierten Codes dynamisch neu kompiliert, da einer der Vorteile der dynamischen Kompilierung darin besteht, dass sie häufig ausgeführte Codeteile („Hot Spots“) erkennen und die Optimierungsaktivität auf diese Hot Spots konzentrieren kann.
-
Eine Schwierigkeit bei der dynamischen binären Optimierung eines Programms unter Verwendung derselben Architektur des Anweisungssatzes ist darauf zurückzuführen, dass der Compiler im Allgemeinen zu Programmoptimierungen alle Register frei verwenden kann, die in der betreffenden Architektur des Anwendungssatzes zur Verfügung stehen. Daher verwendet das Zielprogramm oftmals alle verfügbaren Register, wenn es in seiner ursprünglich kompilierten Form ausgeführt wird. Die dynamische binäre Optimierung wird durch ein anderes Programm durchgeführt, das auf demselben Computer ausgeführt wird, der als „virtuelle Maschine“ bezeichnet wird. Die virtuelle Maschine muss diese selben Register verwenden, weswegen die Registerinhalte im Speicher abgelegt und aus dem Speicher wiederhergestellt werden, wenn Ausführungskontexte zwischen der virtuellen Maschine und dem Zielprogramm umgeschaltet werden. Bei den meisten Computerarchitekturen muss zum Speichern der Register mindestens ein Register zur Verfügung stehen, um Adressdaten des Bereiches im Speicher aufzunehmen, in dem die Register gespeichert werden (der „Kontextspeicherbereich“). Wenn das Zielprogramm so kompiliert wird, dass es alle verfügbaren Register verwendet, gibt es keine Garantie dafür, dass ein Register zum Aufnehmen von Adressdaten des Kontextspeicherbereiches zur Verfügung steht.
-
Obwohl vorgeschlagen worden ist, dieses Problem zu lösen, indem dynamisch nach einem nicht verwendeten Register gesucht, und wenn keines gefunden wurde, der Inhalt des einen oder der mehreren aktiv verwendeten Register vorübergehend im Speicher abgelegt wird („Überlaufen“) entstehen bei dieser Lösung verschiedene Probleme im Zusammenhang mit der exakten Kompatibilität von Registerzuständen und der Datenintegrität/Datensicherheit. Es besteht die nicht zwangsläufig erkannte Notwendigkeit eines besseren Mechanismus zur Unterstützung der dynamischen binären Optimierung und insbesondere der Unterstützung der dynamischen binären Optimierung, bei der dieselbe Architektur des Anweisungssatzes verwendet wird, die das Zielprogramm verwendet.
-
Die
DE 10 2009 041 176 A1 betrifft ein Compiler-System, das einen Compiler umfasst, der dahingehend konfiguriert ist, einen Quellencode zu einem Maschinensprachcode zu kompilieren, so dass der Maschinensprachcode auf einer Verarbeitungseinheit ausführbar ist, wobei die Verarbeitungseinheit ein internes Register umfasst, das ansprechend auf eine Ausführung des Maschinensprachcodes seinen Zustand ändert. Der Compiler ist dahingehend konfiguriert, den Maschinensprachcode auf der Basis einer Verschlüsselungsfunktion, die von dem Zustand des internen Registers abhängt, zu verschlüsseln.
-
Die
DE 692 25 281 T2 betrifft ein Verfahren zum Ausführen einer Codeerzeugung, das in einem Computersystem ausgeführt wird, mit den folgenden Schritten: Anpassen eines Abschnitts eines Zwischensprachengraphen an eine Codeschablone, wobei der Abschnitt des Zwischensprachengraphen mehrere Tupel enthält und eine Darstellung eines ersten Quellprogramms in einer Zwischensprache ist, wobei jedes Tupel eine einzelne Operation darstellt, die in dem ersten Quellprogramm auszuführen ist, wobei die Codeschablone ein vorgegebenes Zwischensprachenmuster enthält, das dem Abschnitt des Zwischensprachengraphen entspricht, um die Erzeugung eines Teils eines ersten Objektmoduls, das dem ersten Quellprogramm entspricht, zu lenken; Analysieren des Abschnitts des Zwischensprachengraphen, um eine Evaluierungsreihenfolge eines Ausdrucks in dem Abschnitt des Zwischensprachengraphen unter Verwendung von Aktionen zu bestimmen, die in der Codeschablone enthalten sind und die die Evaluierungsreihenfolge angeben; Zuordnen eines vorübergehenden Namens an eine Variable unter Verwendung der Aktionen in Übereinstimmung mit der Evaluierungsreihenfolge und Zuweisen einer Zuordnungslebensdauer an den vorübergehenden Namen, wobei die Zuordnungslebensdauer das Ausmaß angibt, in dem der vorübergehende Name und die Speicherung des vorübergehenden Namens der Variable in dem Zwischensprachengraphen zugeordnet sind; Aktualisieren wenigstens eines der mehreren Tupel in dem Abschnitt des Zwischensprachengraphen nach Bedarf, um die Analyse- und Zuordnungsschritte wie durch die Aktionen angegeben auszuführen; und Erzeugen von Maschinensprachenbefehlen, die in dem Teil des Objektmoduls enthalten sind, unter Verwendung der Aktionen und des Zwischensprachengraphen, der wenigstens ein aktualisiertes Tupel enthält.
-
KURZDARSTELLUNG
-
Der Erfindung liegt die Aufgabe zugrunde ein Mittels Computer realisiertes Verfahren zum Ausführen eines Zielprogramms in einem Computersystem, ein Computerprogrammprodukt zum Kompilieren eines Zielprogramms zur Ausführung auf einem Computersystem und ein Digitales Datenverarbeitungssystem zu schaffen, wobei das Verfahren, das Computerprogrammprodukt sowie das Datenverarbeitungssystem eine verbesserte Ausführung eines zu ausführenden Codes unter Einsatz eines dynamischen Binäroptimierers bewirken. Diese Aufgabe wurde durch die Merkmale der nebengeordneten Ansprüche gelöst.
-
Ein Compiler kompiliert zwecks späterer dynamischer binärer Optimierung Code in einem Zielprogramm, indem er mindestens ein Register zur Verwendung durch einen dynamischen Binäroptimierer reserviert, während es bei der Ausführung des Zielprogramms Zustandsdaten enthält. Das heißt, dass der Compiler mit Ausnahme des bzw. der für den dynamischen Binäroptimierer reservierten Register(s) alle verfügbaren Register zur Ausführung des Zielprogramms verwenden kann. Wenn das Programm anschließend ausgeführt wird, speichert der dynamische Binäroptimierer benötigte Zustandsdaten im reservierten Register bzw. in den reservierten Registern, ohne dass sich dies auf den Registerzustand des Zielprogramms auswirkt.
-
Bei der bevorzugten Ausführungsform weisen die im reservierten Register bzw. in den reservierten Registern gespeicherten Zustandsdaten insbesondere Adressierungsdaten für einen Kontextspeicherbereich auf, in dem der Prozesszustand gespeichert wird, wenn die Ausführung des Zielprogramms ausgesetzt wird, sodass der dynamische Binäroptimierer (eine virtuelle Maschine) ausgeführt werden kann. Das Zielprogramm wird mit einem statischen Compiler kompiliert, der eine Option aufweist, um ein oder mehrere Register zur späteren Verwendung bei der dynamischen binären Optimierung zu reservieren. Bei ausgewählter Option kompiliert der Compiler den Code für das Zielprogramm so, als sei die Zahl der zur Verwendung durch das Programm verfügbaren Register gleich der tatsächlichen Anzahl verfügbarer Register, abzüglich der Anzahl von Registern, die zur späteren Verwendung bei der dynamischen binären Optimierung reserviert sind. Dieser statisch kompilierte Code wird gespeichert und kann später mehrfach ausgeführt werden, wobei jede Ausführungsinstanz durch den dynamischen Binäroptimierer getrennt optimiert wird.
-
Vorzugsweise wird nur ein einziges Register reserviert, da im Allgemeinen ein einziges Register ausreicht, um die notwendigen Adressierungsdaten für den Kontextspeicherbereich zu enthalten und es nicht wünschenswert ist, mehr Register als notwendig zu reservieren, da dies die Anzahl von Registern verringert, die zur Ausführung des Zielprogramms zur Verfügung stehen, wodurch das Programm weniger leistungsfähig wird. Im Allgemeinen hat die Reservierung nur eines einzigen Registers nicht mehr als eine unwesentliche Auswirkung auf das Betriebsverhalten das Zielprogramms. Alternativ wäre es noch möglich, weitere Register zu reservieren, was für andere Funktionen des dynamischen Binäroptimierers nützlich wäre.
-
Bei einer beispielhaften Ausführungsform weist ein früher kompiliertes Altprogramm sowohl eine ausführbare Codeversion auf, die durch den Prozessor ausführbare Anweisungen enthält, als auch eine Zwischencodeversion, obwohl der Quellcode nicht notwendigerweise zur Verfügung steht. Das Zielprogramm wird mit einem statischen Compiler kompiliert, der eine Option aufweist, um ein oder mehrere Register zur späteren Verwendung bei der dynamischen binären Optimierung zu reservieren.
-
Bei einer weiteren exemplarischen Ausführungsform wird ein Programm aus seiner Quellcodeversion kompiliert, wobei ein oder mehrere Register zur späteren Verwendung bei der dynamischen binären Optimierung reserviert werden.
-
Die Reservierung eines oder mehrerer Register beim Erzeugen des kompilierten Codes zur Verwendung bei einer späteren dynamischen binären Optimierung gemäß der hierin beschriebenen bevorzugten Ausführungsform stellt eine einfache und wirksame Methode zur Unterstützung der Kontextumschaltung durch einen dynamischen binären Optimierer mit nur minimaler Auswirkung auf das Betriebsverhalten des Zielprogramms bereit.
-
Figurenliste
-
Im Folgenden werden Ausführungsformen der Erfindung unter Bezugnahme auf die beigefügten Zeichnungen beispielhaft beschrieben, wobei:
- 1 ein Übersichtsblockschaltbild der wesentlichen Hardware-Komponenten eines Computersystems ist, das gemäß der bevorzugten Ausführungsform der vorliegenden Erfindung zur dynamischen binären Optimierung von Computerprogrammcode verwendet wird.
- 2 ein Übersichtsblockschaltbild ist, das die wesentlichen Hardware-Komponenten eines Prozessors innerhalb des Computersystems der bevorzugten Ausführungsform zeigt.
- 3 eine konzeptionelle Darstellung der wesentlichen Hardware-Komponenten im Speicher des Computersystems der bevorzugten Ausführungsform ist.
- 4 ein Übersichtsablaufplan ist, der einen allgemeinen Prozess des Erzeugens eines ausführbaren Zielprogramms und des Ausführens des Zielprogramms unter Verwendung eines dynamischen Binäroptimierers gemäß der bevorzugten Ausführungsform zeigt.
- 5 ein Übersichtsablaufplan ist, der einen Prozess des statischen Kompilierens eines oder mehrerer Module eines Zielprogramms zur Ausführung unter Verwendung eines dynamischen Binäroptimierers gemäß der bevorzugten Ausführungsform zeigt.
- 6 ein Übersichtsablaufplan ist, der einen Prozess des Ausführens eines Zielprogramms unter Verwendung eines dynamischen Binäroptimierers gemäß der bevorzugten Ausführungsform zeigt.
-
AUSFÜHRLICHE BESCHREIBUNG
-
Unter Bezugnahme auf die Figuren, in denen gleiche Nummern gleiche Teile bezeichnen, ist 1 eine Übersichtsdarstellung der wesentlichen Hardware-Komponenten eines Computersystems 100, das gemäß der bevorzugten Ausführungsform der vorliegenden Erfindung zur dynamischen binären Optimierung von Computerprogrammcode verwendet wird. Das Computersystem 100 weist mindestens einen programmierbaren Mehrzweckprozessor 101 (CPU) auf, der Anweisungen eines vorgegebenen Anweisungssatzes ausführt und Daten aus dem Hauptspeicher 102 verarbeitet. Bei dem Hauptspeicher 102 handelt es sich vorzugsweise um einen Direktzugriffsspeicher, der eine beliebige von verschiedenen Speichertechnologien verwendet und in den Daten aus dem Speicher oder auf andere Weise zur Verarbeitung durch die CPU 101 geladen werden.
-
Ein oder mehrere Datenaustauschbusse 105 stellen einen Datenaustauschpfad zum Übertragen von Daten zwischen der CPU 101, dem Hauptspeicher 102 und verschiedenen E/A-Schnittstelleneinheiten 111 bis 114 bereit, die möglicherweise auch als E/A-Prozessoren (I/O processors, IOPs) oder E/A-Adapter (I/O adapters, 10As) bekannt sind. Die E/A-Schnittstelleneinheiten unterstützen den Datenaustausch mit einer Vielfalt von Speichereinheiten und E/A-Einheiten. Zum Beispiel unterstützt die Terminalschnittstelleneinheit 111 den Anschluss eines oder mehrerer Benutzerterminals 121 bis 124. Die Speicherschnittstelleneinheit 112 unterstützt den Anschluss einer oder mehrerer Direktzugriffsspeichereinheiten (Direct Access Storage Device, DASD) 125 bis 127 (bei denen es sich in der Regel um rotierende Magnetplatten-Speichereinheiten handelt, obwohl es sich alternativ auch um andere Einheiten handeln könnte, einschließlich Arrays aus Festplattenlaufwerken, die so konfiguriert sind, dass sie gegenüber einem Host als eine einzige große Speichereinheit erscheinen). Die E/A-Einheitenschnittstelleneinheit 113 unterstützt den Anschluss beliebiger verschiedener anderer Arten von E/A-Einheiten wie zum Beispiel eines Druckers 128 und eines Faxgerätes 129, wobei sich versteht, dass andere oder weitere Arten von E/A-Einheiten verwendet werden könnten. Die Netzwerkschnittstelle 114 unterstützt eine Verbindung zu einem oder mehreren externen Netzwerken 130 (von denen eines gezeigt ist) zum Datenaustausch mit einer oder mehreren anderen digitalen Einheiten. Bei dem Netzwerk 130 kann es sich um ein beliebiges von verschiedenen lokalen Netzwerken oder Weitverkehrsnetzwerken handeln, die in der Technik bekannt sind. Beispielsweise kann es sich bei dem Netzwerk 130 um ein lokales Ethernet-Netzwerk oder um das Internet handeln.
-
Es sollte klar sein, dass 1 als Darstellung der charakteristischen wesentlichen Komponenten des Computersystems 100 auf einer hohen Ebene gedacht ist, dass einzelne Komponenten eine größere Komplexität als in 1 dargestellt aufweisen können, dass andere als die in 1 gezeigten oder zusätzliche Komponenten vorhanden sein können, dass die Anzahl, Art und Konfiguration der Hardware-Komponenten variieren kann und dass ein großes Computersystem in der Regel mehr Komponenten als in 1 dargestellt aufweist. Mehrere konkrete Beispiele einer derartigen weiteren Komplexität oder derartiger weiterer Variationen werden hierin offenbart, wobei es sich versteht, dass es sich hierbei lediglich um Beispiele und nicht zwangsläufig um die einzigen derartigen Variationen handelt.
-
Obwohl in 1 zu Veranschaulichungszwecken lediglich eine einzige CPU 101 gezeigt ist, kann das Computersystem 100 mehrere CPUs enthalten, wie in der Technik bekannt ist. Obwohl der Hauptspeicher 102 in 1 als eine einzige, aus einem Block bestehende Einheit gezeigt ist, kann der Speicher 102 in Wirklichkeit verteilt und/oder hierarchisch sein, wie in der Technik bekannt ist. Zum Beispiel kann Speicher auf mehreren Ebenen von Cache-Zwischenspeichern vorhanden sein, und diese Cache-Zwischenspeicher können anhand der Funktion weiter unterteilt sein, sodass ein Cache-Zwischenspeicher Anweisungen enthält, während ein anderer Daten enthält, bei denen es sich nicht um Anweisungen handelt und die durch den Prozessor oder die Prozessoren verwendet werden. Der Speicher kann ferner verteilt sein und zu unterschiedlichen CPUs oder Gruppen von CPUs gehören, wie dies in beliebigen von verschiedenen sogenannten NUMA-Computerarchitekturen (NUMA = Non-Uniform Memory Access) bekannt ist. Obwohl Datenaustauschbusse 105 in 1 als eine einzige Einheit gezeigt sind, wird der Datenaustausch zwischen verschiedenen Systemkomponenten in der Regel über eine komplexe Hierarchie von Bussen, Schnittstellen und so weiter bewerkstelligt, bei der schnellere Pfade für den Datenaustausch zwischen der CPU 101 und dem Speicher 102 verwendet werden und langsamere Pfade für den Datenaustausch mit den E/A-Schnittstelleneinheiten 111 bis 114 verwendet werden. Die Busse 105 können in einer beliebigen von verschiedenen Formen angeordnet sein, zum Beispiel als Punkt-zu-Punkt-Verknüpfungen, parallele und redundante Pfade usw. Beispielsweise können Datenaustauschpfade auf einer Knotenbasis angeordnet sein, wie dies in einer NUMA-Architektur bekannt ist. Busse können z.B. einen Standard-PCI-Bus oder eine beliebige andere geeignete Bustechnologie nutzen. Obwohl mehrere E/A-Schnittstelleneinheiten gezeigt sind, die Busse 105 von verschiedenen Datenaustauschpfaden trennen, die zu den verschiedenen E/A-Einheiten führen, wäre es alternativ möglich, einige oder alle der E/A-Einheiten direkt mit einem oder mehreren Systembussen zu verbinden.
-
Das in 1 abgebildete Computersystem 100 weist mehrere angeschlossene Terminals 121 bis 124 auf, wie dies für Großrechner-Mehrbenutzercomputersysteme typisch sein könnte. In der Regel ist in einem derartigen Fall die tatsächliche Zahl angeschlossener Einheiten größer als in 1 gezeigt, obwohl die vorliegende Erfindung nicht auf Systeme einer beliebigen bestimmten Größe beschränkt ist. Benutzer-Workstations oder Benutzer-Terminals, die auf das Computersystem 100 zugreifen, könnten verwendet werden, um eine Benutzerschnittstelle für Benutzer bereitzustellen, die Anwendungen ausführen, die auf eine Datenbank zugreifen (ähnlich wie Client-Anwendungen, die einen Server aufrufen, um über ein Netzwerk auf eine Datenbank zuzugreifen), die aber ohne die Notwendigkeit des Datenaustauschs über ein Netzwerk direkt auf dem Computersystem 100 ausgeführt werden. Das System 100 kann alternativ ein Einbenutzersystem sein, das in der Regel nur eine einzige Benutzeranzeige und einen einzigen Tastatureingang enthält. Des Weiteren könnte die vorliegende Erfindung, obwohl die Erfindung zu Veranschaulichungszwecken hierin als in einem einzigen Computersystem verkörpert beschrieben ist, alternativ unter Verwendung eines verteilten Netzwerks von Computersystemen realisiert sein, die untereinander im Datenaustausch stehen und in dem hierin beschriebene unterschiedliche Funktionen oder Schritte auf unterschiedlichen Computersystemen durchgeführt werden. Insbesondere könnte die statische Code-Kompilierung eines Zielprogramms auf einem ersten Computersystem durchgeführt werden, während die Ausführung desselben Zielprogramms und die dynamische binäre Optimierung während der Ausführung auf einem zweiten Computersystem durchgeführt werden könnten.
-
Obwohl verschiedene Systemkomponenten auf einer hohen Ebene beschrieben und gezeigt werden, sollte klar sein, dass ein typisches Computersystem viele andere, nicht gezeigte Komponenten enthält, die für ein Verständnis der vorliegenden Erfindung nicht unbedingt notwendig sind. Bei der bevorzugten Ausführungsform handelt es sich bei dem Computersystem 100 um ein Mehrbenutzer-Computersystem auf der Grundlage der IBM i/Series TM-Architektur, wobei klar sein sollte, dass die vorliegende Erfindung auf anderen Computersystemen realisiert sein könnte.
-
2 ist ein Übersichtsblockschaltbild der wesentlichen Komponenten einer zentralen Verarbeitungseinheit (CPU) 101 gemäß der bevorzugten Ausführungsform, die manchmal auch als „Prozessor“ oder „Prozessorkern“ bezeichnet wird, die bestimmte zugehörige Cache-Zwischenspeicherstrukturen aufweist, wobei die CPU 101 mit mehr Einzelheiten als in 1 abgebildet gezeigt ist. Wie bereits zuvor erläutert, kann das System 100 mehrere CPUs enthalten, obwohl in 2 nur eine einzige gezeigt ist. Die CPU 101 weist den Anweisungseinheitsteil 201, den Sonderregisterteil 205 und den Ausführungseinheitsteil 211 auf. Außerdem sind in 2 der Anweisungs-Cache-Zwischenspeicher der Ebene 1 (L1-I-Cache-Zwischenspeicher) 221, der Daten-Cache-Zwischenspeicher der Ebene 1 (L1-D-Cache-Zwischenspeicher) 222, der Cache-Zwischenspeicher der Ebene 2 (L2-Cache-Zwischenspeicher) 223, die Adressumsetzungseinheit 224 und die Speicherschnittstelle 225 gezeigt. Im Allgemeinen empfängt die Anweisungseinheit 201 Anweisungen aus dem L1-I-Cache-Zwischenspeicher 221, decodiert Anweisungen des vorgegebenen Anweisungssatzes der CPU, um durchzuführende Operationen zu ermitteln, und löst Verzweigungsbedingungen auf, um den Programmablauf zu steuern. Die Ausführungseinheit 211 führt arithmetische und logische Operationen an Daten in Registern aus und lädt oder speichert Daten aus dem L1-D-Cache-Zwischenspeicher 222. Die Sonderregister 205 enthalten verschiedene Zustandsdaten zum Steuern des Anweisungsablaufs und der korrekten Funktion der CPU, die die Anweisungseinheit 201 oder die Ausführungseinheit 211 nicht aufweisen. Der L2-Cache-Zwischenspeicher 223 ist ein Cache-Zwischenspeicher der Ebene 2, der im Allgemeinen größer als der L1-I-Cache-Zwischenspeicher 221 oder der L1-D-Cache-Zwischenspeicher 222 ist und dem L1-I-Cache-Zwischenspeicher 221 und dem L1-D-Cache-Zwischenspeicher 222 Daten bereitstellt. Der L2-Cache-Zwischenspeicher 223 empfängt Daten aus einem Cache-Zwischenspeicher einer niedrigeren Ebene (nicht gezeigt) oder über die Speicherschnittstelle 225 aus dem Hauptspeicher.
-
Cache-Zwischenspeicher einer beliebigen Ebene sind logische Erweiterungen des Hauptspeichers. Bei der beispielhaften Ausführungsform sind die L1- und L2-Cache-Zwischenspeicher 221 bis 223 physisch zusammen mit der CPU untergebracht, z.B. sind sie auf demselben integrierten Schaltkreischip wie die CPU realisiert. Aus diesem Grund werden diese Cache-Zwischenspeicher manchmal als Teil der CPU betrachtet. Bei dieser Ausführungsform weist jede CPU jeweils eigene L1- und L2-Cache-Zwischenspeicher auf, die nicht gemeinsam mit anderen CPUs genutzt werden, obwohl es alternativ möglich ist, dass einige oder alle dieser Cache-Zwischenspeicher gemeinsam genutzt werden. Die Darstellung aus 2 ist als typische Darstellung und nicht Einschränkung der vorliegenden Erfindung auf eine bestimmte physische oder logische Realisierungsform von Cache-Zwischenspeichern gedacht. Zu erkennen ist, dass Prozessoren und Cache-Zwischenspeicher in unterschiedlichen Anordnungen ausgeführt sein und der Prozessorchip oder die Prozessorchips mehr Cache-Zwischenspeicher oder weniger Cache-Zwischenspeicher als in 2 dargestellt oder überhaupt keine Cache-Zwischenspeicher aufweisen können.
-
Die Anweisungseinheit 201 weist die Verzweigungseinheit 202, die Decodierungs- und Zuteilungseinheit 203 für Anweisungen und Anweisungsregister und -puffer 204 auf. Anweisungen aus dem L1-I-Cache-Zwischenspeicher 221 werden vor der Ausführung in die Puffer 204 geladen. Je nach der CPU-Ausführung können mehrere Puffer vorhanden sein (z.B. Puffer für unterschiedliche Threads oder innerhalb eines Thread einen Puffer für eine aufeinanderfolgende Reihe von Anweisungen und andere für Orte, zu denen verzweigt werden soll), wobei jeder mehrerer Anweisungen enthalten kann. Die Decodierungs- und Verzweigungseinheit 203 wählt eine oder mehrere Anweisungen aus, die in einem aktuellen Maschinenzyklus von einem oder mehreren Puffern 204 zur Ausführung zugeteilt werden sollen, und decodiert die Anweisung(en) gemäß der Semantik des vorgegebenen Anweisungssatzes des Prozessors, um die durchzuführende(n) Operation(en) oder Verzweigungsbedingungen zu ermitteln. Die Verzweigungseinheit 202 steuert den Programmablauf durch Auswerten von Verzweigungsbedingungen und füllt die Puffer 204 wieder aus dem L1-I-Cache-Zwischenspeicher 221.
-
Die Ausführungseinheit 211 weist eine Gruppe von Mehrzweckregistern 212 zum Speichern von Daten und eine skalararithmetische Logikeinheit (ALU) 213 auf, um als Reaktion auf durch die Anweisungseinheit 201 decodierte Anweisungen arithmetische und logische Operationen an Daten in Mehrzweckregistern (General Purpose Register, GP-Register) 212 durchzuführen. Die Ausführungseinheit 211 kann ferner beliebige verschiedene Datenverarbeitungsuntereinheiten für Sonderzwecke aufweisen. Zum Beispiel ist in 2 eine Untereinheit 214 für Gleitkommaoperationen abgebildet, bei der es sich vorzugsweise um eine spezielle Gleitkomma-Hardware-Pipeline zum Durchführen von Gleitkommaoperationen handelt, bei denen größere Operanden (z.B. 64-Bit-Operanden mit doppelter Genauigkeit) verwendet werden. Wahlweise könnten andere Einheiten für Sonderzwecke (nicht gezeigt) vorhanden sein, wie zum Beispiel eine Untereinheit für Vektoroperationen zum gemeinsamen Durchführen paralleler Operationen an mehreren Operanden. Die Gleitkommauntereinheit 214 (und wahlweise andere Einheiten für Sonderzwecke) weisen jeweils ihre eigene Gruppe von Registern 215 auf. Sowohl die Mehrzweckregister 212 als auch die Gleitkommaregister 215 stehen im Allgemeinen zur Verwendung durch kompilierte Programme zur Verfügung, die auf dem Prozessor 101 ausgeführt werden. Insbesondere kann ein Compiler, der Programme zur Ausführung auf dem Prozessor 101 kompiliert, abhängig davon, wie nach Feststellung des Compilers die effizienteste Ausführung des Programms erzielt werden kann, beliebige oder alle diese Register zum Speichern von frei wählbaren Programmzustandsdaten verwenden. Außer den in 2 gezeigten Komponenten kann die Ausführungseinheit 211 weitere Logik, Zähler, Steuerungs-Hardware und so weiter aufweisen, und sie könnte mehrere Exemplare einiger Einheiten wie zum Beispiel mehrere ALUs 213 aufweisen. Es versteht sich, dass die in 2 dargestellte Ausführungseinheit 211 als repräsentative Darstellung gedacht ist und eine Ausführungseinheit weitere Untereinheiten und Komponenten (einschließlich weiterer Pipelines und Register) oder weniger als alle in 2 gezeigten Komponenten aufweisen kann.
-
Die Sonderregister 205 enthalten bestimmte Zustandsdaten, bei denen es sich nicht um Anweisungen (die in den Anweisungsregistern 204 enthalten sind) und Mehrzweckdaten handelt (die in den Registern 212, 215 enthalten sind), auf deren Grundlage Anweisungen arbeiten. Beispielsweise können die Spezialregister 205 Maschinenzustandsregister 206 aufweisen, die unter anderem Daten enthalten können, die eine Berechtigungsstufe eines gegenwärtig ausgeführten Thread oder gegenwärtig ausgeführter Threads (wenn die CPU die gleichzeitige Ausführung von Threads unterstützt); Interruptvektoren 207 anzeigen; Fehleranzeigen angeben und andere Sonderregister aufweisen können. Insbesondere weisen die Sonderregister 205 ein oder mehrere Kontextumschaltregister 208 auf, die zur Verwendung durch einen speziell berechtigten Prozess wie zum Beispiel einen Betriebssystemkern reserviert sind, um bestimmte Zustandsdaten aufzunehmen, die beim Umschalten von Ausführungskontexten verwendet werden. Das heißt, wenn ein Ausführungsprozess-Thread wegen eines beliebigen von verschiedenen Gründen ausgesetzt wird, um später wiederaufgenommen zu werden, wird der Thread-Zustand und insbesondere der Zustand der Register in einem Kontextspeicherbereich im Speicher 102 gespeichert, bevor ausführbare Anweisungen und Zustandsdaten eines anderen Thread geladen werden und dessen Ausführung auf dem Prozessor begonnen wird. Das Betriebssystem verwendet die Kontextumschaltregister 208 zum Aufnehmen von Daten, die zur Kontextumschaltung benötigt werden, insbesondere von Adressdaten, die den Ort des Kontextspeicherbereiches im Speicher bezeichnen.
-
Der L1-I-Cache-Zwischenspeicher 221 und der L1-D-Cache-Zwischenspeicher 222 sind getrennte Cache-Zwischenspeicher für Anweisungen und Daten, die der Anweisungs- und der Ausführungseinheit Daten bereitstellen, obwohl es sich bei ihnen alternativ um einen einzigen kombinierten Cache-Zwischenspeicher handeln kann. Der L2-Cache-Zwischenspeicher 223 ist ein Cache-Zwischenspeicher, der unterschiedslos sowohl Anweisungen als auch Daten enthält, bei denen es sich nicht um Anweisungen handelt. In der Regel werden Daten durch die Anweisungs- oder Ausführungseinheit aus einem L1-Cache-Zwischenspeicher entnommen oder darin gespeichert, und wenn die Daten in einem L1-Cache-Zwischenspeicher nicht zur Verfügung stehen, werden sie in den L1-Cache-Zwischenspeicher aus dem L2-Cache-Zwischenspeicher 223 geladen, der sie wiederum von einem Cache-Zwischenspeicher einer niedrigeren Ebene oder über die Speicherschnittstelle 225 aus dem Hauptspeicher empfängt. Je nach Prozessorausführung kann es möglich sein, einen Cache-Zwischenspeicher auf einer Ebene zu umgehen und Daten aus einem Cache Zwischenspeicher einer niedrigeren Ebene oder aus einem Speicher zu laden.
-
Die Adressumsetzungseinheit 224 setzt die vom Prozessor erzeugten effektiven Adressen (die bei einigen Architekturen als „virtuelle Adressen“ oder mit einem anderen Namen bezeichnet werden) in entsprechende reale Adressen im Speicher um. Wie in der Technik bekannt ist, besteht ein grundlegender Unterschied zwischen den effektiven Adressen einerseits und den realen Adressen andererseits. Eine effektive Adresse hat keine feststehende Entsprechung zu einer physischen Speicherstelle; diese Entsprechung ändert sich, wenn neue Seiten aus dem Speicher in den Hauptspeicher geladen werden, wenn sich Prozesse ändern und so weiter. Eine tatsächliche Adresse entspricht einer feststehenden physischen Speicherstelle, obwohl sie nicht zwangsläufig direkt auf die Speicherstelle umgesetzt wird. Der Prozessor erzeugt effektive Adressen (die als „virtuell“ oder mit einem ähnlichen Begriff bezeichnet werden können) in einem Adressraum mit effektiven Adressen, der dem jeweiligen ausgeführten Prozess entspricht. Bei einigen Computerarchitekturen sind mehrere Ebenen der effektiven oder virtuellen Adresse vorhanden, die eine weitere Umsetzung erfordern. Eine durch den Prozessor erzeugte effektive Adresse könnte bei einigen Architekturen einfach eine Adresse sein, die in der Anweisung selbst enthalten ist. Bei den meisten modernen Systemen ist der Adressraum mit den effektiven Adressen jedoch im Vergleich zur Größe der Anweisung so groß, dass die Anweisungen keine vollständigen Adressen enthalten. Daher ist eine Adresse in einem Register enthalten, auf das die Anweisung verweist, oder wird als Summe mehrerer Werte empfangen, zum Beispiel eines in der Anweisung enthaltenen Offset-Wertes und eines oder mehrerer Werte, die jeweils in einem entsprechenden Register enthalten sind. Die effektiven Adressen werden ferner entsprechend den tatsächlichen Speicherstellen, an denen sich die Daten befinden, durch die Adressumsetzungseinheit 224 in „reale Adressen“ umgesetzt. Es versteht sich, dass verschiedene Computerarchitekturen unterschiedliche Adressierungskonstrukte nutzen und die vorliegende Erfindung nicht auf eine bestimmte Form der Adressierung beschränkt ist.
-
Der L1-I-Cache-Zwischenspeicher 221 und der L1-D-Cache-Zwischenspeicher 222 werden vorzugsweise unter Verwendung effektiver Adressen adressiert, und daher wird zum Zugreifen auf Cache-Zwischenspeicher der Ebene 1 keine Adressumsetzung benötigt. Der L2-Cache-Zwischenspeicher 223 und alle Speicher unterhalb davon werden jedoch unter Verwendung realer Adressen adressiert. Bei einem notwendigen Zugriff auf einen Cache-Zwischenspeicher einer niedrigeren Ebene oder auf den Hauptspeicher wird daher eine durch den Prozessor erzeugte effektive Adresse zunächst in eine reale Adresse umgesetzt. Es versteht sich, dass L1-Cache-Zwischenspeicher alternativ mit realen Adressen adressiert werden könnten oder beliebige Cache-Zwischenspeicher der niedrigeren Ebenen alternativ mit effektiven Adressen adressiert werden könnten.
-
Die Adressumsetzungseinheit 224 ist als eine einzige logische Einheit dargestellt, weist aber in der Regel mehrere Tabellen und Logikschaltungen auf, die auf verschiedene Chips verteilt sein können. Zum Beispiel kann ein Adressumsetzungsmechanismus einen Adressumsetzungspuffer, eine Tabelle zur Umsetzung effektiver in reale Adressen, eine Segmenttabelle und weitere Strukturen aufweisen. Außerdem könnten separate Strukturen verwendet werden, um Anweisungen und Daten umzusetzen, bei denen es sich nicht um Anweisungen handelt.
-
Die CPU 101 könnte ein Multithread-Prozessor sein, der im selben Maschinenzyklus die gleichzeitige Ausführung mehrerer Threads und die gleichzeitige Zuteilung von Anweisungen aus unterschiedlichen Threads unterstützt, oder es könnte sich um einen Einzelthread-Prozessor handeln. Wenn Multithreading unterstützt wird, ist in der Regel für jeden Thread eine separate Gruppe der maximalen Register vorhanden, d.h., für jeden Thread existiert eine separate Gruppe von Mehrzweckregistern 212 und Gleitkommaregistern 215. Außerdem können bestimmte andere Zustandsregister oder Register für Sonderzwecke vervielfältigt werden, um mehrere aktive Threads zu unterstützen. Die Pipeline-Hardware der Ausführungseinheit, die Anweisungseinheit und die Cache-Zwischenspeicher werden in der Regel von allen Threads gemeinsam genutzt.
-
Obwohl verschiedene CPU-Komponenten auf einer hohen Ebene beschrieben und gezeigt werden, sollte klar sein, dass die CPU der bevorzugten Ausführungsform viele andere, nicht gezeigte Komponenten enthält, die für ein Verständnis der vorliegenden Erfindung nicht unbedingt notwendig sind. Bei einer typischen CPU-Ausführung werden zum Beispiel verschiedene weitere Register für Sonderzwecke benötigt. Des Weiteren versteht es sich, dass die CPU aus 2 einfach nur ein Beispiel einer CPU-Architektur ist und viele Variationen hinsichtlich der Anzahl, Art und Anordnung der Komponenten innerhalb der CPU 101 bestehen könnten, dass außer den abgebildeten Komponenten weitere, nicht gezeigte Komponenten vorhanden und dass nicht alle abgebildeten Komponenten in einer CPU-Ausführung vorhanden sein könnten. Zum Beispiel können die Anzahl und Konfiguration von Puffern und Cache-Zwischenspeichern abweichen; die Anzahl und Funktion von Pipelines der Ausführungseinheit können abweichen; Register können in unterschiedlichen Arrays und Gruppen konfiguriert sein; es kann zweckgebundene Gleitkomma-Hardware vorhanden sein; usw. Des Weiteren kann die CPU 101 einen einfachen oder komplexen Anweisungssatz nutzen.
-
3 ist eine konzeptionelle Darstellung der wesentlichen Hardware-Komponenten des Systems 100 im Speicher 102. Der Betriebssystemkern 301 besteht aus ausführbarem Code und Zustandsdaten, die verschiedene Software Funktionen auf unteren Ebenen bereitstellen, wie zum Beispiel Einheitenschnittstellen, Verwaltung von Speicherseiten, Verwaltung und Zuteilen mehrerer Aufgaben usw., wie in der Technik allgemein bekannt ist. Der dynamische Binäroptimierer 302, der manchmal auch als „virtuelle Maschine“ bezeichnet wird, ist ein ausführbares Programm zum Unterstützen der Ausführung und dynamischen Optimierung eines kompilierten ausführbaren Zielprogramms, wie hierin nachfolgend ausführlicher erläutert wird. Der statische Compiler 303 ist ein ausführbares Computerprogramm, das Quellcodemodule in einer höheren Sprache (oder alternativ Codemodule in einer zuvor analysierten symbolischen Zwischenform) in Objektcodemodule aus durch den Prozessor ausführbaren Anweisungen kompiliert. Das Erstellungsdienstprogramm 304 ist ein ausführbares Computerprogramm, das Anwendungsprogramme durch Einbinden oder Verbinden (auch als „Binden“ bezeichnet) mehrerer, zuvor kompilierter Objektcodemodule und Programme erstellt.
-
Darüber hinaus sind in 3 mehrere Quellcodemodule 311A bis C (hierin allgemein als „Funktion 311“ bezeichnet), mehrere Zwischencodemodule 312A bis C (hierin allgemein als „Funktion 312“ bezeichnet) und mehrere Objektcodemodule 313A bis C (hierin allgemein als „Funktion 313“ bezeichnet) gezeigt. Die Quellcodemodule 311 sind Codemodule in einer höheren Sprache, die unter Verwendung eines Quell-Editors (nicht gezeigt) oder eines Mehrzweck-Editors (nicht gezeigt) erzeugt wurden. Derartige Module könnten auf einem anderen Computersystem erzeugt werden. Zwischencodemodule sind Codemodule in einer symbolischen Zwischensprache, bei der es sich weder um eine höhere Sprache zur Darstellung für den Menschen noch um direkt ausführbaren Code handelt. Beispiele von Zwischencodedarstellungen sind der Stanford P-Code, IBM(TM) W-Code, IBM(TM) NMI-Code (NMI = New Machine Interface) und JAVA(TM)-Bytecodes. Zwischencode wird aus der Quelle durch einen speziellen Parser oder „Frontend-Compiler“ (nicht gezeigt) oder alternativ als Nebenprodukt der Kompilierung durch den statischen Compiler 303 erzeugt. Objektcodemodule 313 sind Module, die durch den Prozessor 101 ausführbare Anweisungen enthalten und durch den statischen Compiler 303 erzeugt werden. Jedes Objektcodemodul wird entweder direkt aus einem entsprechenden Quellmodul 311 oder durch Vorkompilieren eines Quellmoduls in ein Zwischencodemodul 312 und anschließendes Kompilieren des Zwischencodemoduls in ein entsprechendes Objektcodemodul erzeugt.
-
Die Benutzeranwendungsprogramme 314, 315 sind ausführbare Programme, die durch das Erstellungsdienstprogramm 304 aus mehreren Objektcodemodulen 313 erstellt werden. Das Erstellungsdienstprogramm kann ferner beim Erstellen eines Anwendungsprogramms kompilierte Prozeduren aus verschiedenen Programmbibliotheken (nicht gezeigt) einbinden.
-
Der BS-Kern 301 unterstützt die gleichzeitige Ausführung mehrerer Prozesse, wie in der Technik allgemein bekannt ist. Zu jedem gleichzeitig ausgeführten Prozess wird ein entsprechender Prozesszustandsdatenbereich 321 bis 323 aufrechterhalten, wobei jeder Prozesszustandsdatenbereich für jeden ausgeführten Prozess spezifische Zustandsdaten enthält. In 3 sind drei Prozesszustandsdatenbereiche 321 bis 323 abgebildet, wobei sich versteht, dass diese Anzahl variieren kann und in der Regel viel größer ist. Jedes Prozesszustandsdatenelement kann z.B. einen Prozess-Stack, einen Prozess-Heapspeicher und/oder andere Datenstrukturen aufweisen.
-
Insbesondere ist ein Prozess, der über eine Instanz eines dynamischen Binäroptimierers 302 ein Ziel-Benutzeranwendungsprogramm ausführt, als Prozesszustandsdatenbereich 323 dargestellt. Außer beliebigen der verschiedenen Datenstrukturen, die in einem beliebigen Prozesszustandsdatenbereich vorhanden sein können, weist der Prozesszustandsdatenbereich 323 einen Kontextspeicherbereich 324 für das Zielprogramm, einen Cache-Zwischenspeicher 325 für den optimierten Code des Zielprogramms und einen Datenbereich für das Zielprogramm 326 auf. Der Kontextspeicherbereich 324 für das Zielprogramm dient zur zeitweiligen Speicherung des Prozessorzustands, wenn das Zielprogramm durch den Optimierer unterbrochen wird, sodass der Optimierer verschiedene Optimierungsfunktionen durchführen kann. Der Cache-Zwischenspeicher für den optimierten Code des Zielprogramms speichert Zielprogrammcode, der während der dynamischen Optimierung durch den Optimierer verändert wurde; dieser optimierte Code wird nicht zwangläufig gespeichert, und der ursprüngliche ausführbare Code des Zielprogramms bleibt infolge des Ausführens des Zielprogramms mit dem dynamischen Binäroptimierer unverändert. Der Datenbereich 326 für das Zielprogramm enthält Daten, auf die das Zielprogramm während der Ausführung verweist.
-
Verschiedene Softwareeinheiten sind in 3 als separate Einheiten oder als in anderen Einheiten enthalten dargestellt. Es versteht sich jedoch, dass diese Darstellung lediglich der Veranschaulichung dient und bestimmte Module oder Dateneinheiten separate Einheiten oder Teil eines gemeinsamen Moduls oder eines Pakets von Modulen sein könnten. Obwohl in der konzeptionellen Darstellung der 3 eine bestimmte Anzahl und Art von Softwareeinheiten gezeigt sind, versteht es sich des Weiteren, dass die tatsächliche Anzahl derartiger Einheiten variieren kann und dass insbesondere in einer komplexen Computersystemumgebung die Anzahl und Komplexität derartiger Einheiten in der Regel viel größer ist, sowie, dass andere Einheiten (nicht gezeigt) vorhanden sein können. Obwohl aus Gründen der Vollständigkeit der Darstellung die Softwarekomponenten 301 bis 304, 311 bis 315 und 321 bis 326 in 3 in einem einzigen Computersystem 100 abgebildet sind, gilt nicht zwangsläufig, dass alle Programme, Funktionen und Daten in einem einzigen Computersystem vorhanden sind oder auf einem einzigen Computersystem durchgeführt werden. Insbesondere der statische Compiler 303 und/oder das Erstellungshilfsprogramm 304 können sich auf einem anderen System als der dynamische Binäroptimierer 302 befinden, und beliebige der Quellcodemodule 311, Zwischencodemodule 312 oder Objektcodemodule 313 können auf demselben System wie der dynamische Binäroptimierer vorhanden sein. Obwohl aus Gründen der Vollständigkeit Quellmodule in 3 veranschaulicht sind, können in vielen Fällen Quellmodule tatsächlich nicht mehr vorhanden sein, oder wenn sie vorhanden sind, nicht verfügbar sein oder sich an einem unbekannten Speicherort befinden.
-
Obwohl die Softwarekomponenten von 3 konzeptionell als im Speicher 102 befindlich gezeigt sind, versteht es sich, dass der Speicher eines Computersystems im Allgemeinen zu klein sein wird, um gleichzeitig alle Daten und Programme aufzunehmen und Informationen in der Regel in den Datenspeichereinheiten 125 bis 127 gespeichert sind, die eine oder mehrere Massenspeichereinheiten wie zum Beispiel rotierende Magnetplattenlaufwerke aufweisen, und dass die Informationen durch das Betriebssystem je nach Erfordernis seitenweise im Speicher abgelegt werden. Des Weiteren versteht es sich, dass die konzeptionelle Darstellung von 3 nicht stillschweigend ein bestimmtes Modell der Speicherorganisation voraussetzt und das System 100 einen einzigen virtuellen Speicher des Adressraums oder mehrere virtuelle Adressräume nutzen könnte, die sich überlappen.
-
4 ist ein Übersichtsablaufplan, der einen allgemeinen Prozess des Erzeugens eines ausführbaren Zielprogramms und des Ausführens des Zielprogramms unter Verwendung eines dynamischen Binäroptimierers gemäß der bevorzugten Ausführungsform zeigt. Unter Bezugnahme auf 4 kann ein Programm entweder direkt aus dem Quellcode kompiliert werden, wie durch den ab Block 401 beginnenden Ablauf angezeigt, oder es kann aus einer bestimmten Zwischenform des Codes kompiliert werden, wie durch den ab Block 402 beginnenden Ablauf angezeigt. Quellcode kann, wie durch Block 401 angezeigt, durch einen Programmierer in einer beliebigen herkömmlichen Weise erzeugt werden, zum Beispiel mit einem Quelleditor. Gemäß der bevorzugten Ausführungsform werden vom Quellcode keine besonderen Anweisungen oder keine besondere Struktur verlangt, und in der Regel kann beliebiger herkömmlicher Quellcode in einer höheren Sprache dynamisch optimiert werden. Eine Zwischenform des Codes kann durch einen zweckgebundenen speziellen Zwischencodegenerator erzeugt werden oder ein Nebenprodukt vorheriger Kompilierung sein. Zum Beispiel erzeugt der Compiler bei der Plattform IBM i automatisch eine als „NMI-Code“ bekannte Zwischendarstellung und bezieht sie zusammen mit den durch den Prozessor ausführbaren Anweisungen in das kompilierte Programmobjekt ein. Bei Altprogrammen steht der ursprüngliche Quellcode oftmals nicht mehr zur Verfügung. Wenn die ursprüngliche Quelle jedoch auf einer Plattform oder unter Verwendung eines Compilers kompiliert wurde, die bzw. der eine Zwischendarstellung wie zum Beispiel „NMI-Code“ erzeugt, kann das Programm aus der Zwischendarstellung unabhängig davon, dass die ursprüngliche Quelle nicht mehr zur Verfügung steht, erneut kompiliert werden. Die Quelle oder die Zwischencodedarstellung könnten viele Jahre vor der in den Blöcken 403 bis 405 beschriebenen Kompilierung und Ausführung erzeugt worden sein, und sie könnten auf einem anderen System unter Verwendung einer anderen Prozessor- und/oder Betriebssystemarchitektur erzeugt worden sein.
-
Gleichgültig, ob es sich um Quellcode oder eine Zwischendarstellung handelt, ein Compiler kompiliert ein oder mehrere Programmmodule, um Module aus durch den Prozessor ausführbaren Anweisungen zu erzeugen (die auch als Objektcodemodule bezeichnet werden), in denen ein oder mehrere Register zur Verwendung durch einen dynamischen Binäroptimierer reserviert sind. Dieser Kompilierungsprozess ist in 4 in einer Übersichtsform als Block 403 dargestellt und in 5 mit mehr Einzelheiten gezeigt.
-
5 ist ein Übersichtsablaufplan, der einen Prozess des statischen Kompilierens eines oder mehrerer Module des Zielprogramms zur Ausführung unter Verwendung eines dynamischen Binäroptimierers gemäß der bevorzugten Ausführungsform zeigt.
-
Unter Bezugnahme auf 5 wird der statische Compiler 303 aufgerufen und initialisiert (Block 501). Beim Aufruf des Compilers wird eine zu kompilierende Quellcodedatei 311 oder Zwischencodedatei 312 angegeben.
-
Neben verschiedenen anderen Parametern legt der statische Compiler nicht ausdrücklich oder ausdrücklich eine Reihe von Mehrzweckregistern (GP-Register) 212 zur Verwendung durch das Zielprogramm fest, die mit NGP bezeichnet sind (Block 502). Diese Anzahl könnte im Compiler fest codiert sein, aber es ist wahrscheinlicher, dass sie als Eingangsparameter des Compilers empfangen wird. Zum Beispiel könnte der Compiler durch einen Betriebssystemaufruf einen Typ des Prozessors und eine Anzahl von Mehrzweckregistern im Prozessor bzw. in den Prozessoren des Computersystems ermitteln, auf dem er ausgeführt wird, und diese Anzahl als Standard verwenden. Dieser Standard könnte durch eine ausdrückliche Compilerrichtlinie, den Code zur Verwendung in einer anderen Maschine mit einem anderen Prozessortyp zu kompilieren, überschrieben werden.
-
Der Compiler ermittelt ferner, ob er beliebige Mehrzweckregister reservieren soll, die durch einen dynamischen Binäroptimierer bei der Adressierung eines Kontextspeicherbereiches verwendet werden (Block 503). Vorzugsweise wird die Reservierung eines oder mehrerer Register als Reaktion auf eine Compilerrichtlinie durchgeführt. Die Compilerrichtlinie könnte eine Anweisung in der Quellcodedatei 311 oder Zwischencodedatei 312 sein, aber bei der bevorzugten Ausführungsform ist sie ein optionaler Compilerparameter, der beim Aufruf des Compilers durch den Benutzer angegeben wird. Bevorzugt wird, dass es nicht erforderlich ist, dass eine derartige Richtlinie in der Quell- oder Zwischencodedatei eingebettet ist, da derartige Dateien sehr alt sein könnten und es möglicherweise schwierig ist, darin Anweisungen einzufügen, wenn Bearbeitungswerkzeuge oder Frontend-Compiler/Parser nicht mehr zur Verfügung stehen. Es wäre alternativ möglich, dass die Reservierung eines oder mehrerer Register für den dynamischen Binäroptimierer eine Standardoption ist, die automatisch ausgewählt wird, es sei denn, der Benutzer weist den Compiler an, kein Register zu reservieren. Alternativ könnte der Compiler so geschrieben sein, dass er stets mindestens ein Register reserviert, obwohl dies als nicht wünschenswert betrachtet wird, da es Umstände geben kann, unter denen es wünschenswert ist, alle Register zu verwenden.
-
Wenn der Compiler feststellt, dass er ein Register reservieren soll (der „J“-Zweig ab dem Block 503) wird die Anzahl NGP verfügbarer Mehrzweckregister um die Anzahl NR der zu reservierenden Register verringert (Block 504). Bei der bevorzugten Ausführungsform beträgt NR eins, obwohl alternativ eine größere Anzahl verwendet oder durch den Benutzer angegeben werden könnte. Da jedes reservierte Register zwangsläufig die Anzahl von Registern verringert, die dem Compiler für das Zuweisen von Variablen zur Verfügung stehen und daher die Notwendigkeit tendenziell zunimmt, Werte in Register einzulagern und aus diesen auszulagern und dadurch die Leistungsfähigkeit der Ausführung sinkt, ist es nicht wünschenswert, mehr Register als notwendig zu reservieren. Im Allgemeinen reicht ein einziges Register aus, um die Adresse des Kontextspeicherbereiches anzugeben, und daher beträgt NR vorzugsweise eins. Je nach Architektur kann es wünschenswert sein, ein oder mehrere weitere Register für verwandte Kontextspeicheroperationen zu reservieren. Wenn der Compiler bei Block 503 feststellt, dass keine Mehrzweckregister reserviert werden sollen, wird Block 504 umgangen, und der Wert von NGP bleibt unverändert.
-
Wahlweise analysiert der Compiler die Quelldatei 311, um eine symbolische Zwischencodedarstellung und eine Zuordnung von Variablen, Prozedurnamen und so weiter zu erzeugen, die in der Quelle verwendet werden (Block 505). Dieser Prozess wird manchmal als „Frontend-Kompilierung“ bezeichnet. Im Allgemeinen ist dies nur beim direkten Kompilieren aus Quellcode notwendig. Wenn der Compiler aus einer Zwischencodeversion kompiliert, enthält der Zwischencode in der Regel die notwendigen Daten.
-
Der Compiler legt einen Graphen des Steuerungsablaufs an (Block 506). Wie in der Compilertechnik bekannt, ist ein Steuerungsablaufgraph eine Darstellung des Ablaufs der Steuerung in dem gegenwärtig kompilierten Codemodul, der mehrere Knoten und gerichtete Bögen enthält, die die Knoten verbinden, wobei jeder Knoten eine Abfolge von Codeanweisungen mit nur einem einzigen geraden Ausführungspfad und jeder Bogen einen möglichen Pfad (wie zum Beispiel eine Verzweigung) von einem Knoten zu einem anderen darstellt.
-
Unter Verwendung des Steuerungsablaufgraphen wählt der Compiler eine Zuweisung zwischen Programmvariablen und verfügbaren Registern (Block 507), wobei die Anzahl von Mehrzweckregistern, die für diesen Zweck zur Verfügung stehen, NGP beträgt. Eine beliebige der verschiedenen Methoden zur Zuweisung von Registern, die gegenwärtig in der Compilertechnik bekannt sind oder hiernach entwickelt werden, kann verwendet werden, solange die Anzahl verfügbarer Mehrzweckregister auf NGP begrenzt wird. Je nach den Bedürfnissen des Programms und der verwendeten Zuweisungsmethode kann der Compiler, obwohl er dies nicht zwangsläufig tut, alle zur Verfügung stehenden Mehrzweckregister zur Verwendung durch eine oder mehrere Programmvariablen zuweisen, aber in jedem Fall werden die reservierten Register nicht zugewiesen, wenn bei den Blöcken 503 bis 504 ein oder mehrere Mehrzweckregister reserviert wurden.
-
Der Compiler führt unter Verwendung der zuvor getroffenen Registerzuweisungen beliebige unterstützte Codeoptimierungen durch und erzeugt optimierten kompilierten Code (Block 508). Die durchgeführten Optimierungen hängen vom Compiler ab und könnten zum Beispiel die Beseitigung unnötiger Codeanweisungen, die Neuanordnung von Operationen, das Verknüpfen von Aliassen und so weiter aufweisen, wie in der Technik bekannt ist. Es ist nicht entscheidend, dass der Compiler eine bestimmte Optimierung durchführt oder dass es sich bei dem Compiler um einen optimierenden Compiler handelt. Obwohl in 5 dargestellt ist, dass Optimierungen (Block 508) nach der Registerzuweisung durchgeführt werden (Block 507), könnte die Registerzuweisung vor oder nach Optimierungen oder vor bestimmten Optimierungen und nach anderen durchgeführt werden; in der Regel werden zumindest einige Optimierungen vor der Registerzuweisung durchgeführt.
-
Der Compiler wird in der Regel bei jedem zu kompilierenden Codemodul separat aufgerufen. Unterschiedliche Codemodule können etwa zur selben Zeit kompiliert werden, oder sie können zu unterschiedlichen Zeiten kompiliert werden, und sie können auf anderen Maschinen oder auf einer einzelnen Maschine kompiliert werden, die sich von der unterscheidet, auf der sie ausgeführt werden sollen.
-
Unter erneuter Bezugnahme auf 4 wird nach der Kompilierung unter Verwendung des Erstellungshilfsprogramms 304 aus einem oder mehreren kompilieren Objektcodemodulen ein Programm erstellt (Block 404). Das Erstellen ist ein Prozess des Verbindens mehrerer kompilierter Objektcodemodule zu einem einzigen ausführbaren Programm. Das entstandene ausführbare Programm kann z.B. eine einzige Datei sein, die einen Kopf enthält und in der Code aus einem oder mehreren kompilierten Objektcodemodulen enthalten ist und das Bezüge auf externe Objektcodemodule enthalten kann. Je nach der Architektur und/oder der Größe des Programms kann ein Erstellen unnötig sein, und es ist möglich, dass die Kompilierung allein ein Programm in ausführbarer Form erzeugt.
-
Das ausführbare Programm besteht im Allgemeinen aus einer Datei (oder aus mehreren Dateien). Als Programmdatei kann sie auf unbestimmte Zeit auf dem System gespeichert sein und/oder auf ein anderes Computersystem geladen werden. Bei einigen Architekturen wird das Erstellen im Allgemeinen unmittelbar vor der Ausführung durchgeführt.
-
Das Programm wird anschließend unter Verwendung des dynamischen Binäroptimierers ausgeführt. Die Programmausführung ist in 4 in einer Übersichtsform als Block 405 dargestellt und in 6 mit mehr Einzelheiten gezeigt.
-
6 ist ein Übersichtsablaufplan, der einen Prozess des Ausführens eines Zielprogramms unter Verwendung des dynamischen Binäroptimierers 302 gemäß der bevorzugten Ausführungsform zeigt. Unter Bezugnahme auf 6 wird der dynamische Binäroptimierer zur Ausführung des Zielprogramms aufgerufen und ordnet Zustandsdatenstrukturen im betreffenden Prozessdatenbereich zu (Block 601). Der dynamische Binäroptimierer ist selbst ein ausführbares Programm. Bei Ausführung emuliert es eine virtuelle Maschine, die andere ausführbare Programme ausführt, in diesem Fall das Zielprogramm, und somit ist das Zielprogramm ein Programm innerhalb eines Programms. Wie jedes ausführbare Programm wird der dynamische Binäroptimierer im Auftrag eines Benutzerprozesses aufgerufen, wobei der Benutzerprozess einen Prozessdatenbereich aufweist. Ein Prozessdatenbereich für den Prozess, der den dynamischen Binäroptimierer ausführt, ist in 2 als Funktion 323 gezeigt. Zu den Zustandsdaten, die der Binäroptimierer verwaltet, gehören der optimierte Code 325 des Zielprogramms, Daten 326 des Zielprogramms und der Kontextspeicherbereich 324 des Zielprogramms.
-
Der dynamische Binäroptimierer 302 fügt Abfangpunkte in verschiedene kompilierte Zielprogrammmodule ein (Block 602). Jeder Abfangpunkt bewirkt, dass die Ausführung der Codefolge des Zielprogramms anhält und die Steuerung an den dynamischen Binäroptimierer zurückgibt. Ein Abfangpunkt könnte nichts weiter als eine einzelne durch den Prozessor ausführbare Anweisungsverzweigung auf eine vorgegebene Codefolge des Optimierers selbst sein. Abfangpunkte werden an geeigneten Stellen eingefügt, um den Ablauf der Ausführung des Zielprogramms zu überwachen und zu ermitteln, ob ausgewählte Codeteile zu optimieren sind. Zum Beispiel kann bei jedem Aufruf oder bei jeder Rückkehr von einer Prozedur ein Abfangpunkt eingefügt werden.
-
Nach dem Initialisieren und Einfügen beliebiger notwendiger Abfangpunkte springt der dynamische Binäroptimierer zu einem Eintrittspunkt im kompilierten Zielprogramm (Block 603), wodurch ein Segment der durch den Prozessor ausführbaren Anweisungen des Zielprogramms direkt auf dem Prozessor 101 ausgeführt wird (Block 604). Obwohl das Wort „Segment“ verwendet wird, sind weder die Anweisungen, die ausgeführt werden, nicht zwangsläufig zusammenhängend im adressierbaren Speicher abgelegt, noch ist das Segment zwangsläufig von einer beliebigen vorgegebenen Größe. Es ist einfach ein Teil des Programms, der einen oder mehrere Austrittspunkte und an jedem Austrittspunkt entsprechende eingefügte Abfangpunkte aufweist. Während der Ausführung des Segments können die durch den Prozessor ausführbaren Anweisungen des Segments auf Daten im Datenbereich 326 des Zielprogramms verweisen und Daten aus diesem Bereich des Speichers in derselben Weise laden und speichern, als würden sie direkt und ohne Eingriff des dynamischen Binäroptimierers ausgeführt. Die Ausführung des Programmsegments wird bis zum Auftreten eines Abfangpunktes fortgesetzt (Block 605).
-
Vorzugsweise bewirkt der Abfangpunkt einen Sprung zu einem vorgegebenen Codesegment innerhalb des dynamischen Binäroptimierers selbst. Die wichtigste Aufgabe bei der Behandlung eines Abfangpunktes besteht darin, den Zustand des Prozessors zu speichern (Block 606). Zu diesem Zweck wird das reservierte Mehrzweckregister (GP-Register R) verwendet, um den Kontextspeicherbereich 324 des Zielprogramms zu adressieren. Beispielsweise könnte die erste vorgefundene Anweisung nach dem Springen zur Abfangpunktposition darin bestehen, den Inhalt des GP-Registers 0 an der durch das GP-Register R bezeichneten effektiven Speicheradresse zu speichern; eine zweite Anweisung könnte darin bestehen, den Inhalt des GP-Registers 1 an der effektiven Speicheradresse zu speichern, die durch die Summe des Wertes im GP-Register R und einem angegebenen Offset bezeichnet wird, und so weiter. Während die Inhalte der verschiedenen Mehrzweckregister gespeichert werden, werden diese Register zur Verwendung durch den dynamischen Binäroptimierer beim Speichern anderer Zustandsdaten verfügbar, wodurch mehr als ein einziges Register erforderlich sein kann. Daher wird wie beschrieben nur ein einziges reserviertes Register zum Speichern des Zustands des Prozessors benötigt.
-
Nachdem der Prozessorzustand des Zielprogramms gespeichert worden ist, kann der dynamische Binäroptimierer beliebige gewünschte Optimierungsfunktionen durchführen. Der Optimierer ermittelt, ob die Ausführung des Zielprogramms abgeschlossen ist (Block 607). Wenn nicht (der „N“-Zweig ab Block 607), aktualisiert der Optimierer jegliche Ausführungsdaten, die zum Durchführen von Optimierungen verwendet werden (Block 608). Beispielsweise überwacht ein Optimierer in der Regel die Häufigkeit der Ausführung ausgewählter Codesegmente und optimiert und kompiliert Code erneut, wenn das Segment häufig ausgeführt wird. Der Optimierer kann sich außerdem dazu entscheiden, Code erneut zu kompilieren, der als besonders ineffizient betrachtet wird. Der Optimierer verwendet daher diese Ausführungsdaten, um zu ermitteln, ob ein Codesegment (wie zum Beispiel eine Prozedur) erneut optimiert werden sollte (Block 609). Wenn die Entscheidung getroffen wird, ein Codesegment erneut zu optimieren, wird das entsprechende Codesegment erneut optimiert und kompiliert (Block 610) und im Bereich 325 für optimierten Zielprogrammcode gespeichert. Oftmals handelt es sich bei einem erneut zu kompilierenden Segment um ein Segment, das sonst als nächstes ausgeführt würde.
-
Bei der bevorzugten Ausführungsform gehören zu den Optimierungen, die durch den dynamischen Binäroptimierer durchgeführt werden können, Optimierungen, die Aliasdaten nutzen, und insbesondere Optimierungen mit einer Neuordnung der Ausführung bestimmter Operationen, deren Aliasdaten anzeigen, dass sie sicher neu geordnet werden können. Zu diesem Zweck werden Aliasdaten vorzugsweise zum Zeitpunkt der Kompilierung in Objektcodemodule 313 eingebettet. Diese Methode ist ausführlicher in der gemeinsam erteilten US-Patentanmeldung mit der Seriennummer 13/016038 beschrieben, die zum selben Zeitpunkt wie die vorliegende Anmeldung eingereicht wurde, mit „Using Aliasing Information for Dynamic Binary Optimization“ (Aktenzeichen des Abtretungsempfängers ROC920100267US1) betitelt ist und durch Bezugnahme einen Bestandteil der vorliegenden Anmeldung bildet. Bei einer alternativen Ausführungsform sind derartige Aliasdaten jedoch nicht vorhanden und/oder werden nicht zur Optimierung verwendet.
-
Wenn der Optimierer das Aktualisieren seiner Daten abgeschlossen und beliebige gewünschte Optimierungen durchgeführt hat, lädt er den Prozessorzustand erneut aus dem Kontextspeicherbereich des Zielprogramms und setzt den Wert des GP-Registers R auf die Adresse des Anfangs des Kontextspeicherbereiches zurück (Block 611). Anschließend springt er zu der Stelle im Code, an der die Ausführung des Zielprogramms ausgesetzt wurde (Block 612), und das nächste Programmsegment wird ausgeführt (Block 604).
-
Wenn das Zielprogramm die Ausführung beendet hat (d.h., es trifft auf einen Abfangpunkt an einem Austrittspunkt im Programm), wird der „J“-Zweig ab Block 607 eingeschlagen. Der Optimierer führt anschließend beliebige abschließende Bereinigungen der Datenstrukturen, die Ausgabe von Daten usw. durch und beendet die Ausführung (Block 613).
-
Wie oben beschrieben werden zu Beginn der Ausführung bei Block 602 mehrere Abfangpunkte eingefügt. Der Optimierer könnte jedoch alternativ in jedem Zielprogrammsegment an jedem seiner Austrittspunkte unmittelbar, bevor das Segment auszuführen ist, einen oder mehrere Abfangpunkte einfügen (wenn diese nicht zuvor eingefügt wurden), wodurch die Notwendigkeit vermieden wird, Abfangpunkte in Programmsegmente einzufügen, die nie ausgeführt werden. Des Weiteren gibt es, obwohl das Einfügen von Abfangpunkten hierin als beispielhafte Ausführungsform offenbart ist, alternative Methoden, durch die ein dynamischer Binäroptimierer die Steuerung des Prozessors erlangen kann. Zum Beispiel verwenden einige Systeme regelmäßige Interrupts, um den Programmzähler abzufragen und zu entscheiden, wann ein Codesegment optimiert werden soll. Alternativ können Hardware-Unterstützungseinheiten vorhanden sein, um die Erfassung von Verzweigungswegen zu erleichtern und den Optimierer aufzurufen.
-
In der Regel erzeugt der dynamische Binäroptimierer keinen dauerhaft optimierten Code, der länger als der Benutzerprozess besteht, der dessen Erzeugung verursacht hat. Je nach der Realisierungsform des dynamischen Binäroptimierers ist es einem einzelnen Benutzerprozess möglich, das Programm mehrere Male auszuführen und den während einer früheren Ausführung erzeugten optimierten Code wiederzuverwenden. Sobald der Benutzerprozess jedoch endet, werden die Optimierungen nicht gespeichert. Dies ist das Wesen der dynamischen binären Optimierung. Wenn das zuvor kompilierte Programm anschließend unter Verwendung des dynamischen Binäroptimierers in einem anderen Benutzerprozess erneut ausgeführt wird, beginnt der Optimierer in der Regel mit dem bei Block 403 statisch kompilierten und bei Block 404 erstellten Programm von neuem, ohne in einem vorherigen Benutzerprozess vorgenommene vorherige Optimierungen zu nutzen.
-
Obwohl in den Ablaufplänen eine bestimmte Reihenfolge von Operationen veranschaulicht und im beigefügten Text beschrieben ist, versteht es sich, dass in Übereinstimmung mit der vorliegenden Erfindung einige Operationen in einer anderen Reihenfolge durchgeführt werden könnten, einige Operationen nicht durchgeführt zu werden brauchen und stattdessen andere Operationen durchgeführt werden können.
-
Im Allgemeinen werden die Routinen, die zur Realisierung der veranschaulichenden Ausführungsformen der vorliegenden Erfindung ausgeführt werden, unabhängig davon, ob sie als Teil eines Betriebssystems oder als bestimmte Anwendung, bestimmtes Programm, Objekt, Modul oder als bestimmte Reihenfolge von Anweisungen einschließlich eines Moduls innerhalb einer speziellen Einheit wie zum Beispiel eines Serviceprozessors realisiert sind, hierin als „Programme“ oder' „Steuerungsprogramme“ bezeichnet. Die Programme weisen in der Regel Anweisungen auf, die, wenn sie durch einen oder mehrere Prozessoren in den Einheiten oder Systemen in einem der Erfindung entsprechenden Computersystem gelesen oder ausgeführt werden, bewirken, dass diese Einheiten oder Systeme die Schritte durchführen, die notwendig sind, um Schritte auszuführen oder Elemente zu erzeugen, die die verschiedenen Aspekte der vorliegenden Erfindung verkörpern. Darüber hinaus können die verschiedenen Ausführungsformen der Erfindung, obwohl die Erfindung im Kontext voll funktionsfähiger Computersysteme beschrieben wurde und beschrieben wird, als Programmprodukt verteilt werden, dass auf nichtflüchtigen computerlesbaren Speichermedien verkörpert ist, und die Erfindung gilt gleichermaßen unabhängig von der Form der Verteilung. Zu Beispielen nichtflüchtiger computerlesbarer Medien gehören, ohne darauf beschränkt zu sein, flüchtige und nichtflüchtige Speichereinheiten, Disketten, Festplattenlaufwerke, CD-ROMs, DVDs und Magnetband, wobei sich versteht, dass es sich hierbei nicht um erschöpfende Beispiel handelt. Beispiele nichtflüchtiger computerlesbarer Medien sind in 1 als Systemspeicher 102 und Datenspeichereinheiten 125 bis 127 veranschaulicht.
-
Sofern nicht mit der Erfindung unvereinbar oder anderweitig hierin eingeschränkt, kann Computerprogrammcode zur Ausführung von Operationen der vorliegenden Erfindung in einer beliebigen Kombination aus einer oder mehreren Programmiersprachen geschrieben sein, darunter in einer objektorientierten Programmiersprache wie Java, Smalltalk, C++ oder Ähnlichem und in herkömmlichen prozeduralen Programmiersprachen wie „C“ oder ähnlichen Programmiersprachen. Der Programmcode kann vollständig auf dem Computer des Benutzers, teilweise auf dem Computer des Benutzers, als eigenständiges Softwarepaket, teilweise auf dem Computer des Benutzers und teilweise auf einem entfernt angeordneten Computer oder vollständig auf dem entfernt angeordneten Computer oder Server ausgeführt werden. Beim letztgenannten Szenario kann der entfernt angeordnete Computer mit dem Computer des Benutzers über eine beliebige Art von Netzwerk verbunden sein, unter anderem über ein lokales Netzwerk (LAN) oder über ein Weitverkehrsnetzwerk (WAN), oder die Verbindung kann zu einem externen Computer hergestellt werden (beispielsweise über das Internet unter Nutzung eines Internet-Dienstanbieters (Internet Service Provider)).
-
Die vorliegende Erfindung ist hierin unter Bezugnahme auf Ablaufpläne und/oder Blockschaltbilder von Methoden, Vorrichtungen (Systemen) und Computerprogrammprodukten gemäß Ausführungsformen der Erfindung beschrieben. Es versteht sich, dass jeder Block der Ablaufpläne und/oder der Blockschaltbilder und Kombinationen von Blöcken in den Ablaufplänen und/oder Blockschaltbildern durch Computerprogrammanweisungen realisiert werden kann bzw. können. Diese Computerprogrammanweisungen können einem Prozessor eines Mehrzweckcomputers, eines Spezialcomputers oder anderen programmierbaren Datenverarbeitungsvorrichtungen bereitgestellt werden, um eine Maschine zu erzeugen, sodass die Anweisungen, die über den Prozessor des Computers oder anderer programmierbarer Datenverarbeitungsvorrichtungen ausgeführt werden, Mittel zum Realisieren der in einem Block bzw. in den Blöcken des Ablaufplans und/oder des Blockschaltbildes angegebenen Funktionen/Aktionen schaffen.
-
Diese Computerprogrammanweisungen können auch in einem nichtflüchtigen computerlesbaren Medium gespeichert sein, das einen Computer oder andere programmierbare Datenverarbeitungsvorrichtungen anweisen kann, in einer bestimmten Weise zu funktionieren, sodass die im nichtflüchtigen computerlesbaren Medium gespeicherten Anweisungen ein Produkt zu schaffen, das die Anweisungen enthält, die die in einem Block bzw. in den Blöcken des Ablaufplans und/oder des Blockschaltbildes angegebene Funktion/Aktion realisiert.
-
Diese Computerprogrammanweisungen können auch in einen Computer oder in andere programmierbare Datenverarbeitungsvorrichtungen geladen werden, um zu bewirken, dass auf dem Computer oder auf anderen programmierbaren Vorrichtungen eine Reihe von Arbeitsschritten ausgeführt werden, um einen mittels Computer realisierten Prozess zu schaffen, mit dessen Hilfe die Anweisungen, die auf dem Computer oder auf anderen programmierbaren Vorrichtungen ausgeführt werden, Prozesse zur Realisierung der in einem Block bzw. in den Blöcken des Ablaufplans und/oder des Blockschaltbildes angegebenen Funktionen/Aktionen bereitstellen.
-
Die Ablaufpläne und die Blockschaltbilder in den Figuren veranschaulichen die Architektur, Funktionalität und Wirkungsweise möglicher Realisierungsformen von Systemen, Verfahren und Computerprogrammprodukten gemäß den verschiedenen Ausführungsformen der vorliegenden Erfindung. Dementsprechend kann jeder einzelne Block im Ablaufplan bzw. in den Blockschaltbildern ein Modul, ein Segment oder einen Teil des Codes darstellen, der eine oder mehrere ausführbare Anweisungen zur Realisierung der angegebenen Logikfunktion bzw. Logikfunktionen aufweist. Außerdem sollte beachtet werden, dass bei einigen alternativen Realisierungsformen die im Block angegebenen Funktionen in einer anderen als der in den Figuren angegebenen Reihenfolge ausgeführt werden können. Beispielsweise können zwei hintereinander aufgeführte Blöcke tatsächlich im Wesentlichen gleichzeitig ausgeführt werden, oder die Blöcke können je nach der damit verbundenen Funktionalität manchmal in umgekehrter Reihenfolge ausgeführt werden. Darüber hinaus ist anzumerken, dass jeder Block der dargestellten Blockschaltbilder und/oder des dargestellten Ablaufplans sowie Kombinationen von Blöcken in den dargestellten Blockschaltbildern und/oder im dargestellten Ablaufplan mithilfe von bestimmten Zwecken dienenden, hardwaregestützten Systemen zur Ausführung der angegebenen Funktionen bzw. Aktionen oder mithilfe von Kombinationen aus bestimmten Zwecken dienender Hardware und Computeranweisungen realisiert werden kann bzw. können.
-
Obwohl eine bestimmte Ausführungsform der Erfindung zusammen mit bestimmten Alternativen offenbart wurde, ist für den Fachmann klar, dass innerhalb des Schutzbereiches der folgenden Ansprüche weitere Variationen in Form und Detail vorgenommen werden können.