-
HINTERGRUND
-
Gebiet der Erfindung
-
Die vorliegende Erfindung betrifft allgemein das Optimieren von Code auf der Grundlage einer Vielzahl unterschiedlicher Prozessorarchitekturrealisierungen oder genauer das Auswählen des ausführbaren Codes, der für eine Architekturrealisierung eines spezifischen Prozessors optimiert ist.
-
Beschreibung des Standes der Technik
-
Quellcode (d. h. Text, der unter Verwendung des Formats und der Syntax einer Programmiersprache geschrieben ist) kann so kompiliert werden, dass er zum Ausführen auf einem bestimmten Prozessor optimiert ist. Zum Beispiel kann der Prozessor eine bestimmte Funktionseinheit besitzen, die der ausführbare Code vorteilhaft nutzen kann. Wenn der ausführbare Code, der für die bestimmte Prozessorarchitekturrealisierung optimiert ist, jedoch auf einem Prozessor mit einer anderen Architekturrealisierung ausgeführt wird, kann die Leistungsfähigkeit des ausführbaren Codes darunter leiden.
-
KURZDARSTELLUNG
-
Ausführungsformen der Erfindung stellen ein Verfahren, ein System und ein Computerprogrammprodukt zum Auswählen von optimiertem Code bereit, der auf einem Rechensystem auszuführen ist, das einen ersten Prozessor und einen zweiten Prozessor aufweist.
-
In einer Ausführungsform weisen das Verfahren und das Computerprogrammprodukt ein Laden von durch den ersten oder den zweiten Prozessor auszuführendem ausführbarem Code auf, wobei der ausführbare Code auf computerlesbarem Code beruht und wobei mindestens ein Teil des computerlesbaren Codes durch einen Kompilierer optimiert wird, um sowohl einen ersten, auf einer Architekturrealisierung des ersten Prozessors beruhenden kompilierten Codeteil als auch einen zweiten, auf einer Architekturrealisierung des zweiten Prozessors beruhenden kompilierten Codeteil zu erzeugen. Weiterhin unterscheiden sich die jeweiligen Architekturrealisierungen des ersten und des zweiten Prozessors. Bei Ermitteln, dass der ausführbare Code dem ersten Prozessor zugewiesen ist, weisen das Verfahren und das Computerprogrammprodukt ein Ausführen des ersten kompilierten Codeteils und nicht des zweiten kompilierten Codeteils auf dem ersten Prozessor auf. Bei Ermitteln, dass der ausführbare Code dem zweiten Prozessor zugewiesen ist, weisen das Verfahren und das Computerprogrammprodukt ein Ausführen des zweiten kompilierten Codeteils und nicht des ersten kompilierten Codeteils auf dem zweiten Prozessor auf.
-
In einer weiteren Ausführungsform weist das System einen ersten Prozessor und einen zweiten Prozessor auf, wobei sich die jeweiligen Architekturrealisierungen des ersten und des zweiten Prozessors unterscheiden. Das System weist einen Lader auf, der so eingerichtet ist, dass durch ihn durch den ersten oder den zweiten Prozessor auszuführender ausführbarer Code ladbar ist, wobei der ausführbare Code auf computerlesbarem Code beruht. Mindestens ein Teil des computerlesbaren Codes wird durch einen Kompilierer optimiert, um sowohl einen ersten, auf einer Architekturrealisierung des ersten Prozessors beruhenden kompilierten Codeteil als auch einen zweiten, auf einer Architekturrealisierung des zweiten Prozessors beruhenden kompilierten Codeteil zu erzeugen. Bei Ermitteln, dass der ausführbare Code dem ersten Prozessor zugewiesen ist, führt der erste Prozessor den ersten kompilierten Codeteil und nicht den zweiten kompilierten Codeteil aus. Bei Ermitteln, dass der ausführbare Code dem zweiten Prozessor zugewiesen ist, führt der zweite Prozessor den zweiten kompilierten Codeteil und nicht den ersten kompilierten Codeteil aus.
-
In einer weiteren Ausführungsform weist ein Verfahren zum Kompilieren von auf einem Computersystem mit einem ersten Prozessor und einem zweiten Prozessor auszuführendem ausführbarem Code ein Optimieren mindestens eines Teils des computerlesbaren Codes auf, um einen ersten, auf einer Architekturrealisierung des ersten Prozessors beruhenden kompilierten Codeteil zu erzeugen. Das Verfahren weist ein Optimieren des Teils des computerlesbaren Codes auf, um einen zweiten, auf einer Architekturrealisierung des zweiten Prozessors der Vielzahl von Prozessoren beruhenden kompilierten Codeteil zu erzeugen, wobei sich die jeweiligen Architekturrealisierungen des ersten und des zweiten Prozessors unterscheiden. Das Verfahren weist ein Erzeugen von auf dem computerlesbaren Code beruhendem ausführbarem Code durch Betrieb eines oder mehrerer Computerprozessoren auf, wobei der ausführbare Code eines aufweist von: (i) dem ersten und dem zweiten kompilierten Codeteil und (ii) mindestens einem Bezug auf den ersten und den zweiten kompilierten Codeteil.
-
KURZBESCHREIBUNG DER ZEICHNUNGEN
-
Damit die Art und Weise, in der die vorstehend wiedergegebenen Aspekte erreicht werden, detailliert verstanden werden kann, ist eine genauere Beschreibung von Ausführungsformen der vorstehend kurz dargestellten Erfindung unter Bezugnahme auf die angehängten Zeichnungen vorhanden.
-
Es ist jedoch festzuhalten, dass die angehängten Zeichnungen nur typische Ausführungsformen dieser Erfindung veranschaulichen und daher nicht als deren Umfang einschränkend anzusehen sind, da die Erfindung andere, gleichermaßen wirksame Ausführungsformen zulassen kann.
-
Die 1A bis 1B zeigen Blockschaubilder, die ein Netzwerksystem zum Durchführen von durch Clients übermittelten Jobs auf einem Mehrknotensystem gemäß Ausführungsformen der Erfindung veranschaulichen.
-
2 zeigt ein Schaubild, das gemäß einer Ausführungsform der Erfindung das Kompilieren von Code veranschaulicht, der für eine Vielzahl von Prozessoren optimiert ist.
-
3 zeigt gemäß einer Ausführungsform der Erfindung einen Ablaufplan zum Ausführen von optimiertem Code, der statisch im System der 1A bis 1B verbunden ist.
-
4 zeigt gemäß einer Ausführungsform der Erfindung einen Ablaufplan zum Ausführen von optimiertem Code, der dynamisch oder statisch im System der 1A bis 1B verbunden ist.
-
5 zeigt ein Schaubild, das ein Mehrknoten-Jobkonstrukt gemäß Ausführungsformen der Erfindung veranschaulicht.
-
DETAILLIERTE BESCHREIBUNG
-
Parallele Computersysteme enthalten üblicherweise eine Vielzahl von Computerknoten, die einen oder mehrere Computerprozessoren beinhalten. In manchen Fällen handelt es sich um einheitliche Computerprozessoren – d. h. sie nutzen dieselbe Architekturrealisierung gemeinsam. Ein Kompilierer kann Quellcode für das Ausführen auf der gemeinsamen Prozessorarchitekturrealisierung optimieren. Diese Computersysteme können dann den kompilierten Code einem Prozessor zuweisen, der beispielsweise am wenigsten ausgelastet ist. Dementsprechend ist der Code unabhängig vom für das Ausführen des Quellcodes gewählten Computerprozessor für die Architekturrealisierung des Computerprozessors optimiert. Andere Computersysteme können jedoch Rechenknoten aufweisen, die Prozessoren mit einer Vielfalt unterschiedlicher Architekturrealisierungen enthalten. Darüber hinaus können diese Computersysteme zudem einem Prozessor ausführbaren Code auf der Grundlage des am wenigsten ausgelasteten Prozessors zuweisen. Wenn der Code somit für einen spezifischen Prozessor optimiert wurde, jedoch einem Prozessor mit einer anderen Architekturrealisierung zugewiesen wurde, weil dieser die meiste CPU-Rechenleistung zur Verfügung hat, kann der Code schlechter ausgeführt werden, als wenn er überhaupt nicht optimiert worden wäre. Eine Lösung besteht darin, für den ausführbaren Code das Ausführen auf dem Prozessor zu erzwingen, für den er optimiert ist; wenn dieser Prozessor jedoch ausgelastet ist, kann dies zu Leistungseinbußen des Computersystems führen.
-
Stattdessen kann ein Kompilierer den Code für das Ausführen auf zwei oder mehr unterschiedlichen Architekturrealisierungen optimieren. Wenn zum Beispiel ein Rechenknoten drei unterschiedliche Prozessortypen (d. h. drei unterschiedliche Prozessorarchitekturrealisierungen) aufweist, kann der Kompilierer so eingerichtet sein, dass Quellcode für das Ausführen auf den drei unterschiedlichen Typen optimierbar ist. Das heißt, nach dem Kompilieren des Quellcodes kann das sich ergebende ausführbare Element die notwendigen Informationen zum Ausführen von Code enthalten, der für alle drei unterschiedlichen Prozessorarchitekturrealisierungen optimiert ist. Wenn ein Programmlader dem Prozessor das ausführbare Element zuweist, ermittelt das System den Typ des Prozessors und stellt sicher, dass nur der diesem Typ entsprechende optimierte Code ausgeführt wird. Somit kann der Lader ohne Weiteres den ausführbaren Code jedem Prozessor zum Beispiel auf der Grundlage der Leistungsfähigkeit oder des Status des Prozessors (z. B. ob er verfügbare CPU-Verarbeitungsleistung besitzt) zuweisen und nach wie vor die Vorteile des Ausführens von Code nutzen, der für den Prozessor optimiert ist.
-
Nachfolgend wird Bezug auf die Ausführungsformen der Erfindung genommen. Es ist jedoch zu beachten, dass die Erfindung nicht auf bestimmte beschriebene Ausführungsformen beschränkt ist. Stattdessen wird jede beliebige Kombination der folgenden Merkmale und Elemente betrachtet, um die Erfindung auszubilden und auszuführen, wobei es unerheblich ist, ob sie unterschiedlichen Ausführungsformen angehören oder nicht. Obwohl weiterhin Ausführungsformen der Erfindung Vorteile gegenüber anderen möglichen Lösungen und/oder gegenüber dem Stand der Technik erzielen können, wird die Erfindung nicht dadurch eingeschränkt, ob ein bestimmter Vorteil durch eine gegebene Ausführungsform erzielt wird. Somit sind die folgenden Aspekte, Merkmale, Ausführungsformen und Vorteile der Erfindung lediglich veranschaulichend und nicht als Elemente oder Einschränkungen der angehängten Ansprüche anzusehen, außer wo dies ausdrücklich in einem Anspruch angegeben ist. Gleichfalls ist die Bezugnahme auf „die Erfindung” nicht als Verallgemeinerung jedes hierin offenbarten Gegenstands der Erfindung und nicht als Element oder Einschränkung der angehängten Ansprüche zu betrachten, außer wo dies ausdrücklich in einem oder mehreren Ansprüchen angegeben ist.
-
Wie für den Fachmann ersichtlich ist, können Aspekte der vorliegenden Erfindung als System, Verfahren, oder Computerprogrammprodukt ausgebildet werden. Dementsprechend können Aspekte der vorliegenden Erfindung in Form einer vollständigen Hardwareausführungsform, einer vollständigen Softwareausführungsform (darunter Firmware, residente Software, Mikrocode usw.) oder in einer Ausführungsform ausgebildet werden, die Software- und Hardwareaspekte kombiniert, was hierin sämtlich allgemein als „Schaltung”, „Modul” oder „System” bezeichnet sein kann. Weiterhin können Aspekte der vorliegenden Erfindung in Form eines Computerprogrammprodukts ausgebildet werden, das in einem oder mehreren computerlesbaren Medien mit darauf befindlichem computerlesbarem Programmcode enthalten sein kann.
-
Jede beliebige Kombination aus einem oder mehreren computerlesbaren Medien kann verwendet werden. Bei dem computerlesbaren Medium kann es sich um ein computerlesbares Signalmedium oder ein computerlesbares Speichermedium handeln. Bei einem computerlesbaren Speichermedium kann es sich zum Beispiel, ohne auf diese beschränkt zu sein, um ein System, eine Vorrichtung oder eine Einheit elektronischer, magnetischer, optischer, elektromagnetischer, Infrarot oder Halbleiter verwendender Art sowie eine beliebige geeignete Kombination des Vorgenannten handeln. Zu spezielleren Beispielen für das computerlesbare Speichermedium kann Folgendes gehören (nicht erschöpfende Liste): eine elektrische Verbindung mit einer oder mehreren Leitungen, eine transportable Computerdiskette, eine Festplatte, ein Speicher mit wahlfreiem Zugriff (RAM), ein Nur-Lese-Speicher (ROM), ein löschbarer programmierbarer Nur-Lese-Speicher (EPROM oder Flash-Speicher), ein Lichtwellenleiter, ein transportabler Compact-Disk-Nur-Lese-Speicher (CD-ROM), eine optische Speichereinheit, eine magnetische Speichereinheit oder eine beliebige geeignete Kombination des Vorgenannten. Im Kontext dieses Dokuments kann es sich bei einem computerlesbaren Speichermedium um jedes gegenständliche Medium handeln, das ein Programm zur Verwendung durch oder in Verbindung mit einem System, einer Vorrichtung oder einer Einheit zur Ausführung von Anweisungen beinhalten oder speichern kann.
-
Ein computerlesbares Signalmedium kann ein verbreitetes Datensignal mit darin zum Beispiel in einem Basisband oder als Teil einer Trägerwelle ausgebildetem computerlesbarem Programmcode beinhalten. Solch ein verbreitetes Signal kann in jeder beliebigen einer Vielfalt von Formen ausgebildet werden, wie beispielsweise, jedoch nicht beschränkt auf, elektromagnetische, optische oder jede geeignete Kombination davon. Bei einem computerlesbaren Signalmedium kann es sich um ein beliebiges computerlesbares Medium handeln, das kein computerlesbares Speichermedium ist und das ein Programm zur Verwendung durch oder in Verbindung mit einem System, einer Vorrichtung oder einer Einheit zur Ausführung von Anweisungen übertragen, verbreiten oder transportieren kann.
-
Der in einem computerlesbaren Medium enthaltene Programmcode kann mittels eines beliebigen geeigneten Mediums übertragen werden wie beispielsweise, jedoch nicht beschränkt auf, drahtlose, drahtgebundene, Lichtwellenleiterkabel, Hochfrequenz (HF) usw., oder einer beliebigen geeigneten Kombination des Vorgenannten.
-
Computerprogrammcode zum Ausführen von Operationen für Aspekte der vorliegenden Erfindung kann in jeder Kombination einer oder mehrerer Programmiersprachen, darunter eine objektorientierte Programmiersprache wie Java, Smalltalk, C++ oder Ähnliches und herkömmliche prozedurale Programmiersprachen wie die Programmiersprache „C” oder ähnliche Programmiersprachen geschrieben sein. 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. In letzterem Szenario kann der entfernt angeordnete Computer mit dem Computer des Benutzers über jede beliebige Art von Netzwerk, darunter ein Nahbereichsnetzwerk (local area network (LAN)) oder ein Weitbereichsnetzwerk (wide area network (WAN)) verbunden sein, oder es kann eine Verbindung zu einem externen Computer (zum Beispiel mittels eines Internetdienstanbieters über das Internet) hergestellt werden.
-
Aspekte der vorliegenden Erfindung werden nachfolgend unter Bezugnahme auf Abbildungen von Ablaufplänen und/oder Blockschaubildern von Verfahren, Vorrichtungen (Systemen) und Computerprogrammprodukten gemäß Ausführungsformen der Erfindung beschrieben. Es versteht sich, dass jeder Block der Abbildungen von Ablaufplänen und/oder der Blockschaubilder sowie Kombinationen von Blöcken in den Abbildungen von Ablaufplänen und/oder den Blockschaubildern durch Computerprogrammanweisungen realisiert werden kann. Diese Computerprogrammanweisungen können einem Prozessor eines universellen Computers, eines zweckbestimmten Computers oder einer anderen programmierbaren Datenverarbeitungsvorrichtung bereitgestellt werden, um eine Maschine so zu erzeugen, dass die Anweisungen, die über den Prozessor des Computers oder der anderen programmierbaren Datenverarbeitungsvorrichtung ausgeführt werden, ein Mittel zum Realisieren der im Block oder in den Blöcken des Ablaufplans und/oder Blockschaubildes angegebenen Funktionen/Handlungen erzeugen.
-
Diese Computerprogrammanweisungen können auch in einem computerlesbaren Medium gespeichert sein, das einen Computer, eine andere programmierbare Datenverarbeitungsvorrichtung oder andere Einheiten anleiten kann, auf eine bestimmte Weise zu funktionieren, so dass die in dem computerlesbaren Medium gespeicherten Anweisungen einen Herstellungsartikel einschließlich Anweisungen erzeugen, welche die im Block oder in den Blöcken des Ablaufplans und/oder des Blockschaubildes angegebene Funktion/Handlung ausführen.
-
Die Computerprogrammanweisungen können auch auf einen Computer, eine andere programmierbare Datenverarbeitungsvorrichtung oder andere Einheiten geladen werden, um eine Reihe von auf dem Computer, der anderen programmierbaren Vorrichtung oder den anderen Einheiten auszuführenden Operationsschritten hervorzurufen, um einen auf dem Computer realisierten Prozess so zu erzeugen, dass die auf dem Computer oder der anderen programmierbaren Vorrichtung ausgeführten Anweisungen Prozesse zum Realisieren der im Block oder in den Blöcken des Ablaufplans und/oder Blockschaltbildes angegebenen Funktionen/Handlungen bereitstellen.
-
Die 1A bis 1B zeigen Blockschaubilder, die ein Netzwerksystem zum Durchführen von durch Clients übermittelten Jobs auf einem Mehrknotensystem gemäß Ausführungsformen der Erfindung veranschaulichen. Wie gezeigt, handelt es sich bei 1A um ein Blockschaubild, das ein Netzwerksystem zum Durchführen von durch Clients übermittelten Jobs auf einem Mehrknotensystem veranschaulicht. In der dargestellten Ausführungsform enthält das System 100 ein Client-System 120 und ein Mehrknotensystem 170, die durch ein Netzwerk 150 verbunden sind. Allgemein übermittelt das Client-System 120 einem auf dem Mehrknotensystem 170 laufenden Dateisystem Jobs über das Netzwerk 150. Nichtsdestoweniger kann jede anfragende Einheit dem Mehrknotensystem 170 Jobs übermitteln. Zum Beispiel können Softwareanwendungen (wie beispielsweise eine auf dem Client-System 120 laufende Anwendung), Betriebssysteme, Teilsysteme, andere Mehrknotensysteme 170 und, auf höchster Ebene, Benutzer Jobs übermitteln. Der Begriff „Job” bezeichnet einen Satz von Befehlen zum Anfordern von Ressourcen vom Mehrknotensystem 170 und zum Verwenden dieser Ressourcen. Jede beliebige Programmiersprache wie Java, Smalltalk, C++, C oder Ähnliches kann zum Bilden des Satzes von Befehlen realisiert werden. Zudem kann ein Mehrknotensystem 170 eine eindeutige Programmiersprache realisieren oder eine bestimmte Vorlage bereitstellen. Diese Jobs können zuvor festgelegt (d. h. als Teil einer Anwendung fest programmiert) sein oder als Reaktion auf Eingaben (z. B. Benutzereingaben) erzeugt werden. Bei Erhalten des Jobs führt das Mehrknotensystem 170 die Anfrage aus und gibt dann das Ergebnis aus.
-
Bei 1B handelt es sich um ein Blockschaubild eines Netzwerkcomputersystems das zum Durchführen von durch Clients übermittelten Jobs auf einem Mehrknotensystem gemäß einer Ausführungsform der Erfindung eingerichtet ist. Wie gezeigt, beinhaltet das System 100 ein Client-System 120 und ein Mehrknotensystem 170. Das Client-System 120 beinhaltet einen Computerprozessor 122, Speichermedien 124, einen Speicher 128 und eine Netzwerkschnittstelle 138. Bei dem Computerprozessor 122 kann es sich um jeden Prozessor handeln, der in der Lage ist, die hierin beschriebenen Funktionen durchzuführen. Das Client-System 120 kann mittels der Netzwerkschnittstelle 138 mit dem Netzwerk 150 verbunden sein. Wie für den Fachmann ersichtlich ist, kann des Weiteren jedes Computersystem verwendet werden, dass in der Lage ist, die hierin beschriebenen Funktionen durchzuführen.
-
In der abgebildeten Ausführungsform enthält der Speicher 128 ein Betriebssystem 130 und eine Client-Anwendung 132. Obwohl der Speicher 128 als einzelne Einheit gezeigt ist, können zum Speicher 128 auch eine oder mehrere Speichereinheiten mit Speicherblöcken zählen, die physischen Adressen zugeordnet sind, wie beispielsweise ein Speicher mit wahlfreiem Zugriff (RAM), ein Nur-Lese-Speicher (ROM), ein Flash-Speicher oder andere Arten flüchtigen und/oder nichtflüchtigen Speichers. Die Client-Anwendung 132 ist allgemein in der Lage, Jobanfragen zu erzeugen. Sobald die Client-Anwendung 132 einen Job erzeugt, kann der Job über das Netzwerk 150 an das Dateisystem 172 zur Ausführung übermittelt werden. Bei dem Betriebssystem 130 kann es sich um jedes Betriebssystem handeln, das in der Lage ist, die hierin beschriebenen Funktionen durchzuführen.
-
Das Mehrknotensystem 170 beinhaltet ein Dateisystem 172 und mindestens einen Knoten 190. Jede Jobdatei 174 enthält die notwendigen Informationen für die Knoten 190, um einen übermittelten Job ausführen zu können. Der Aktualisierer 182 unterhält einen Datensatz darüber, welche Jobdateien anhängig sind, d. h. durch einen Knoten 190 ausgeführt werden. Die Netzwerkschnittstelle 184 ist mit dem Netzwerk 150 verbunden und empfängt die vom Client-System 120 gesendeten Jobdateien 174. Wie für den Fachmann ersichtlich ist, kann des Weiteren jedes Computersystem verwendet werden, dass in der Lage ist, die hierin beschriebenen Funktionen durchzuführen.
-
In einer Ausführungsform kann die Jobdatei 174 in einer Programmiersprache (z. B. C++, C, Assembler-Sprache und Ähnliches) geschriebenen Quellcode oder ausführbaren Code (z. B. Objektcode oder Maschinencode) enthalten.
-
Die Knoten 190 enthalten Computerprozessoren 192 und einen Speicher 194. Bei den Computerprozessoren 192 kann es sich um jeden Prozessor handeln, der in der Lage ist, die hierin beschriebenen Funktionen durchzuführen. Der hierin verwendete Begriff „Prozessor” schließt mindestens eine Ausführungseinheit ein, die in ausführbarem Code gefundene Anweisungen verarbeitet. Dementsprechend kann jeder Kern innerhalb eines Mehrfachkernprozessors als ein separater Prozessor bezeichnet werden.
-
Die Computerprozessoren 192 können in unterschiedliche Prozessortypen weiter unterteilt werden, wobei jeder Typ eine bestimmte Architekturrealisierung besitzt. Jeder Prozessortyp kann zum Beispiel nach Einzelstrangverarbeitung, Durchsatzfähigkeiten, Nachrichtenabwicklung, Hilfsfließkommaeinheiten, Vektoreinheiten, Fließkommaeinheiten und Ähnlichem unterschieden werden. Somit können die hierin verwendeten Prozessoren, die „unterschiedliche Architekturrealisierungen” besitzen, nach wie vor dieselbe Anweisungssatzarchitektur (×86, PowerPC usw.) verwenden, jedoch unterschiedliche Funktionseinheiten oder eine unterschiedliche Anordnungen dieser Hardwareeinheiten besitzen.
-
Obwohl sich in einer Ausführungsform die Architekturrealisierungen von zwei oder mehreren der Computerprozessoren 192 unterscheiden, sind die Prozessoren softwarekompatibel. Das heißt, die Architekturrealisierung sind ähnlich genug, dass jeder auf einem der Prozessoren 192 ausführbare Code auch auf jedem anderen der Computerprozessoren 192 ausgeführt werden kann, auch wenn der Code speziell für eine der Architekturrealisierungen optimiert wurde. Die Leistungsfähigkeit des Mehrknotensystems 170 oder des Codes kann jedoch abhängig von dem der Ausführung des Codes zugewiesenen Prozessor 192 variieren. Zum Beispiel kann der Prozessor 192 eine Mikrocode- Maschine (Engine) zur Abwicklung bestimmter Anweisungen in der ISA aufweisen. Er kann dies tun, um ISA-Kompatibilität aufrechtzuerhalten, ohne umfangreiche Hardwareressourcen für den Leistungsvorteil zuzuweisen, den die Anweisung bietet. Falls dem so ist, kann bei der Verwendung der Anweisung die Leistungsfähigkeit leiden, im Vergleich zu der Situation, dass die Anweisung vermieden und ein Anweisungsstrom eingefügt wird, der dem ähnelt, den die Mikrocode-Maschine verwendet haben würde. Dadurch könnte der Prozessor jeglichen Arbeitsaufwand in Verbindung mit der Mikrocode-Maschine vermeiden. Nichtsdestoweniger kann ein Prozessor, der diese Anweisungen nicht mikrocodiert, sondern mit dem beschleunigten Kern softwarekompatibel ist, auch Objektcode ausführen, der für das vorteilhafte Nutzen der Mikrocode-Maschine im beschleunigten Kern optimiert wurde. Somit ist der Rechenknoten in der Lage, den ausführbaren Code jedem der Computerprozessoren 192 im Rechenknoten 190 zuzuweisen, der softwarekompatibel ist.
-
Der Speicher 194 enthält ein Betriebssystem 198 und einen Kompilierer 197. Zum Speicher 194 können auch sowohl der innerhalb des Prozessors 192 befindliche Cachespeicher als auch eine oder mehrere Speichereinheiten mit Speicherblöcken zählen, die physischen Adressen zugeordnet sind wie beispielsweise ein Speicher mit wahlfreiem Zugriff (RAM), ein Nur-Lese-Speicher (ROM), ein Flash-Speicher oder andere Arten flüchtigen und/oder nichtflüchtigen Speichers.
-
Das Betriebssystem 198 beinhaltet einen Lader 195 und einen Verbinder 196, und es kann sich dabei um jedes Betriebssystem handeln, das in der Lage ist, die hierin beschriebenen Funktionen durchzuführen. Der Lader 195 ist für das Laden von Programmen (d. h. ausführbaren Elementen) in den Speicher und deren Vorbereiten für das Ausführen zuständig. Zum Laden eines Programms gehört das Lesen der Inhalte eines ausführbaren Elements, das den ausführbaren Code enthält, in den Speicher 194 und das Ausführen aller anderen vorbereitenden Aufgaben, um den ausführbaren Code vorzubereiten. Nachdem der Lader 195 seine Funktion durchgeführt hat, übergibt das Betriebssystem die Steuerung an den geladenen ausführbaren Code.
-
In einer Ausführungsform kann der Lader 195 den Prozessortyp ermitteln, der den ausführbaren Code ausführen wird. Zum Beispiel kann der Lader 195 die im ID-Register 199 im Computerprozessor 192 gespeicherte Identifikationsnummer lesen.
-
Das heißt, jeder Prozessor (oder Verarbeitungskern) 192 kann eine ID besitzen, die der Lader 195 zum Identifizieren der Architekturrealisierung des Prozessors und somit dessen Typs verwenden kann. Nach Ermitteln des Prozessortyps stellt der Lader 195 sicher, dass der für diesen Prozessor optimierte ausführbare Code ausgeführt wird.
-
Der Verbinder 196 kann für Programme verwendet werden, die dynamisch mit Bibliotheken verbunden sind. Um Speicherplatz zu sparen und den Umfang der ausführbaren Elemente zu verringern, kann der ausführbare Code Bezüge auf Code aufweisen, der in einer oder mehreren Bibliotheken gespeichert ist. Während der Laufzeit, d. h. nachdem der ausführbare Code einem bestimmten Prozessor zugewiesen wurde, löst der Verbinder 196 die Bezüge auf und lädt die erforderlichen Bibliotheken in den Speicher. Der Verbinder 196 kann zudem den Typ des Prozessors 192 ermitteln, um sicherzustellen, dass der korrekte optimierte Code durch den Prozessor 192 ausgeführt wird. Die Funktionen des Laders 195 und des Verbinders 196 werden später detaillierter erläutert.
-
Der Kompilierer 197 ist so eingerichtet, dass er Quellcode in der Weise optimieren kann, dass das sich ergebende ausführbare Element (oder die Datei) so eingerichtet ist, dass Code ausführbar ist, der für mindestens zwei unterschiedliche Prozessortypen im Mehrknotensystem 170 optimiert ist. Wenn zum Beispiel der ausführbare Code statisch verbunden ist (d. h. der ausführbare Code unabhängig ist, so dass er keine Bezüge auf Bibliotheken enthält, die zur Laufzeit aufgelöst werden müssen), erzeugt der Kompilierer 197 für jeden der Prozessortypen eine separate Version einer oder mehrerer Subroutinen im optimierten Code. Wenn somit der Knoten 190 drei unterschiedliche Typen von Prozessoren aufweist, erzeugt der Kompilierer 197 ein ausführbares Element, das die notwendigen Informationen zum Ausführen der korrekten Version des ausführbaren Codes für die drei unterschiedlichen Typen besitzt.
-
Obwohl der Kompilierer 197 im Mehrknotensystem 170 gezeigt ist, kann das Client-System 120 (z. B. die Client-Anwendungen 132) in einer Ausführungsform einen Kompilierer aufweisen, der die hierin beschriebenen Funktionen besitzt. Wenn somit dem System 170 eine Job-Datei 174 übermittelt wird, kann der Quellcode zuvor kompiliert worden sein.
-
Darüber hinaus können die Prozessoren 192 des Mehrknotensystems 170 in einer Ausführungsform so eingerichtet sein, dass ein oder mehrere Stränge in einer oder mehreren Pipelines ausführbar sind. Somit kann es sich bei jedem Strang um ein separates ausführbares Element handelt, das durch den Kompilierer 197 erzeugt wird. Die ausführbaren Elemente können Teil eines größeren Jobs sein, der dem Mehrknotensystem 170 übermittelt wird, wodurch das System 170 die ausführbaren Elemente und somit den Job parallel ausführen kann. In anderen Ausführungsformen kann dieselbe Verfahrensweise auf ein Computersystem angewandt werden, das ausführbare Arbeitsströme erzeugt, die auf einer Vielzahl von Prozessoren parallel ausgeführt werden.
-
2 zeigt ein Schaubild, das gemäß einer Ausführungsform der Erfindung das Kompilieren von Code veranschaulicht, der für eine Vielzahl von Prozessoren optimiert ist. Ein Quellcode 202 kann als Text geschrieben sein und den Formatierungsansprüchen einer Programmiersprache wie Java, C, C++ und Ähnlichem genügen. Üblicherweise kann der Quellcode 202 so geschrieben sein, dass er eine oder mehrere Subroutinen 204, 206 enthält. Abhängig von der Programmiersprache kann es sich bei den Subroutinen 204, 206 um eine Prozedur, eine Funktion, eine Routine, ein Verfahren, ein Teilprogramm und Ähnliches handeln. Die hierein erläuterten Ausführungsformen offenbaren das Optimieren einer oder mehrerer der Subroutinen 204 und 206 auf der Grundlage einer bestimmten Architekturrealisierung eines Prozessors. Zum Beispiel kann ein Kompilierer so eingerichtet sein, dass er unter Umständen nur eine oder zwei der Subroutinen 204, 206 im Quellcode 202 oder alternativ dazu alle Subroutinen 204, 206 optimiert. In einer Ausführungsform kann ein Benutzer den Kompilierer anweisen, welche Subroutinen 204, 206 für die Vielzahl von Prozessortypen in einem Rechensystem zu optimieren sind. Obwohl in den Ausführungsformen das Optimieren von Subroutinen erläutert wird, ist die Erfindung nicht darauf beschränkt und kann bei Programmiersprachen verwendet werden, die keine Subroutinen besitzen, oder bei Kompilierern, die den gesamten Quellcode 202 ungeachtet der darin befindlichen Subroutinen optimieren.
-
Die Benutzersubroutine 204 steht für jede benutzerspezifische Subroutine, die durch einen Programmierer in den Quellcode eingefügt werden kann. Bei einer Benutzersubroutine 204 kann es sich auch um einen Bezug auf eine zugehörige Datei oder einen Aufruf einer anderen zugehörigen Datei handeln, die Quellcode enthält. Im Gegensatz dazu steht die Bibliotheksubroutine 206 für Aufrufe von Subroutinen im Quellcode 202, die in Standard- oder benutzerspezifischen Bibliotheken zu finden sind. Zum Beispiel beinhaltet die Programmiersprache „C” eine Standardbibliothek – „stdio.h” – mit der ein Benutzer die Funktion „printf” (d. h. eine Subroutine) verwenden kann, um Informationen anzuzeigen. Das Einfügen einer Bibliotheksubroutine 206 in den Quellcode 202 erlaubt dem Programmierer die Verwendung der Funktionalität der Subroutine, ohne den gesamten zugehörigen Quellcode einfügen zu müssen. Vor oder während des Ausführens des kompilierten Quellcodes (d. h. dem ausführbaren Element) lädt ein Kompilierer oder Verbinder den notwendigen ausführbaren Code von der Bibliothek, um die Bibliotheksubroutine 206 auszuführen.
-
In einer Ausführungsform kann der Quellcode 202 so kompiliert werden, dass er statisch verbunden ist. Wie nach dem Stand der Technik bekannt ist, löst statisches Verbinden alle Aufrufe von Bibliotheksubroutinen 206 (oder Aufrufe anderer externer Subroutinen und Variablen) während der Kompilierzeit auf. Somit erzeugt der Kompilierer (oder Verbinder oder Binder) eigenständigen ausführbaren Code (d. h. Objektcode innerhalb eines ausführbaren Elements), der keine Bezüge auf Bibliotheken enthält. Wenn dementsprechend der ausführbare Code durch einen Prozessor ausgeführt wird, kann für die Anwendung sichergestellt sein, dass all ihre Bibliotheken vorhanden sind und in der korrekten Version vorliegen. Dadurch können zudem Abhängigkeitsprobleme vermieden werden.
-
Zum Beispiel kann der Quellcode 202 durch einen statisch verbindenden Kompilierer 208 kompiliert werden. Der statisch verbindende Kompilierer 208 löst alle Bezüge im Quellcode auf externe Subroutinen (z. B. Bibliotheksubroutinen 206) auf, um unabhängigen ausführbaren Code (d. h. ein ausführbares Element oder ein Teil davon) zu erzeugen. Das heißt, der Kompilierer 208 verwendet den Quellcode 202 und die (nicht gezeigten) Bibliotheken, auf die Bezug genommen wird, um den ausführbaren Code 210 zu erzeugen, der durch eine Vielzahl von Prozessoren 192 im Mehrknotensystem 170 ausgeführt werden kann, ohne Bezüge während der Laufzeit auflösen zu müssen.
-
Wie in 2 gezeigt, enthält der ausführbare Code 210 zwei Optionen 214, 220, die jeweils zwei unterschiedlichen Typen von Prozessoren entsprechen, die den Code 210 ausführen können. Jede Option 214, 220 beinhaltet Code, der für das Ausführen auf einer bestimmten Architekturrealisierung eines Prozessors optimiert ist. Hier enthält die Option 214 ausführbaren Code, der für den Prozessor 1 optimiert ist, während die Option 220 ausführbaren Code enthält, der für den Prozessor 2 optimiert ist. Insbesondere enthält die Option 214 ausführbaren Code für das Ausführen der Benutzersubroutine 204 auf dem Prozessor 1 (d. h. user_sub_on_proc1 216) und ausführbaren Code für das Ausführen der Bibliotheksubroutine 206 auf dem Prozessor 1 (d. h. lib_sub_on_proc1 218). Der Kompilierer 208 erzeugt diese ausführbaren Codeteile unter Verwendung des Quellcodes der Benutzersubroutine 204 bzw. der Bibliotheksubroutine 206. Die ausführbaren Codeteile sind speziell für den Prozessor 1 optimiert. Unter Verwendung desselben Quellcodes 202 und derselben Bibliotheken erzeugt der Kompilierer 208 zudem eine andere Version ausführbaren Codes, die für den Prozessor 2 – d. h. die Option 220 – optimiert ist. Diese Option 220 enthält ausführbaren Code für das Ausführen der Benutzersubroutine 204 auf dem Prozessor 2 (d. h. user_sub_on_proc2 222) und ausführbaren Code für das Ausführen der Bibliotheksubroutine 206 auf dem Prozessor 2 (d. h. lib_sub_on_proc2 224).
-
In einer Ausführungsform fügt der Kompilierer 208 dem ausführbaren Code 210 Auswahlcode 212 hinzu, der dem Prozessor Anweisungen zum Auswählen der geeigneten auszuführenden Option bereitstellt. Insbesondere entspricht der Auswahlcode 212 keinem Teil des Quellcodes 202, sondern wurde vielmehr durch den Kompilierer 208 eingeführt, um den Code 210 mit der Fähigkeit zum Wählen zwischen der Option 214 und der Option 220 zu versehen. Auf diese Weise ist die Fähigkeit des ausführbaren Codes 210, zwischen optimierten Codeteilen auszuwählen, für den Programmierer, der den Quellcode 202 erzeugt hat, transparent.
-
Der Auswahlcode 210 weist ausführbaren Code auf, der so eingerichtet ist, dass er den Typ des Prozessors erkennen kann, der den ausführbaren Code 210 ausführt, und dann auf der Grundlage des identifizierten Prozessortyps die auszuführende Option 214, 220 auswählen kann. Nachdem zum Beispiel ein Lader den ausführbaren Code 210 in den Hauptspeicher verschoben hat und das Betriebssystem die Steuerung des Prozessors dem ausführbaren Code 210 übergeben hat, wird der Auswahlcode 212 durch den Prozessor ausgeführt. Während der Ausführung kann der Auswahlcode 212 auf das ID-Register zugreifen und auf der Grundlage der ID des Prozessors die Architekturrealisierung (und den Typ) des Prozessors ermitteln. Der Auswahlcode 210 weist dann den Prozessor an, die korrekte Option 214, 220 auszuführen. Wenn es sich bei dem Prozessor um den Prozessor 1 handelt, wird der in der Option 214 enthaltene ausführbare Code ausgeführt, wohingegen der in der Option 220 enthaltene ausführbare Code nicht ausgeführt wird. Das Gegenteil trifft ebenso zu.
-
Alternativ dazu, enthält der ausführbare Code 210 unter Umständen nicht den Auswahlcode 210, und stattdessen kann der Lader ermitteln, welche Option 214, 220 ausgeführt werden soll. Das heißt, der Lader verwendet das ID-Register, um die Architekturrealisierung und den Typ des Prozessors zu identifizieren, dem der ausführbare Code zugewiesen ist, und weist den Prozessor an, wo mit dem Ausführen des Codes 210 begonnen werden soll – d. h., entweder die Option 214 oder die Option 220 auszuführen. Auf diese Weise ermittelt das Betriebssystem, welche Option 214, 220 auszuführen ist, anstatt, dass der ausführbare Code 210 die Logik zum Durchführen der Analyse enthält.
-
In einer Ausführungsform kann ein dynamisch verbindender Kompilierer 226 verwendet werden, um diesen Quellcode 202, Bibliotheken, auf die Bezug genommen wird, und Aufrufe externer Funktionen oder Variablen zu optimieren und zu kompilieren. Anstelle des Erzeugens unabhängiger ausführbarer Elemente erzeugt der Kompilierer 226 ausführbaren Code 228 (d. h. ein ausführbares Element oder ein Teil eines ausführbaren Elements), der Bezüge (d. h. Verbindungen oder Symbole) auf Standardbibliotheken oder durch den Benutzer erstellte Bibliotheken beinhaltet. Um den Umfang ausführbarer Elemente zu verringern, erlauben viele Programmiersprachen das Kompilieren von Code, ohne dass der gesamte notwendige ausführbare Code innerhalb des ausführbaren Elements enthalten ist. Stattdessen fügt der Kompilierer Bezüge ein, die später während der Laufzeit aufgelöst werden. Bei diesen Bezügen kann es sich um Speicheradressen oder Dateipfade zur Bibliothek handeln, die den ausführbaren Code enthält.
-
Wie gezeigt, weist der ausführbare Code 228 vier Bezüge auf, die jeweils eine Verbindung mit unterschiedlichen Versionen ausführbaren Codes für die unterschiedlichen Prozessorarchitekturrealisierungen darstellen, die im Mehrknotensystem 170 anzutreffen sind. Der Bezug 230 auf eine Benutzersubroutine für den Prozessor 1 stellt eine Verbindung mit der Bibliothek user_sub_proc1 238 dar, die den der Benutzersubroutine 204 zugehörigen ausführbaren Code enthält, der für das Ausführen auf dem Prozessor 1 optimiert ist. Der Bezug 232 auf die Benutzersubroutine für den Prozessor 2 stellt eine Verbindung mit der Bibliothek user_sub_proc2 240 dar. Die Bezüge 234 und 236 auf Bibliotheksubroutinen für den Prozessor 1 und den Prozessor 2 stellen eine Verbindung mit lib_sub_proc1 242 bzw. lib_sub_proc2 244 dar. Bevor daher der ausführbare Code 228 durch einen Prozessor ausgeführt wird, müssen die Bezüge aufgelöst werden – d. h., der Prozessor benötigt eine Möglichkeit, den in den Bibliotheken 246 anzutreffenden ausführbaren Code zu finden.
-
Obwohl 2 für jede kompilierte Version der Benutzer- oder Bibliotheksubroutinen 204, 206 das Einfügen eines separaten Bezugs in den ausführbaren Code 226 zeigt, fügt der Kompilierer 197 in einer Ausführungsform unter Umständen nur einen einzigen generischen Bezug ein, der alle unterschiedlichen Versionen einer Subroutine widerspiegelt. Dieser generische Bezug kann auf eine oder mehrere Bibliotheken verweisen, in denen die Versionen gespeichert sind. Nachdem der ausführbare Code 228 einem Prozessor zugewiesen wurde, kann der Verbinder die Architekturrealisierung des zugewiesenen Prozessors erkennen und durch die eine oder mehreren durch den generischen Bezug wiedergegebenen Bibliotheken analysieren, um die Bibliothek (oder den Teil einer Bibliothek) zu finden, welche die Version der Subroutine enthält, die der Architekturrealisierung entspricht. Der Verbinder lädt unter Umständen nur diese relevante Bibliothek in den Speicher und schließt die anderen Bibliotheken aus, die durch den generischen Bezug verbunden wurden. Dann kann der Verbinder den Bezug auflösen, indem die Speicheradresse zur relevanten Bibliothek im Speicher eingefügt wird.
-
Zu den Bibliotheken 246 können Standardbibliotheken für die gewählte Programmiersprache (z. B. die Funktion „printf” in der Programmiersprache C) oder Bibliotheken zählen, die auf der Grundlage von im Quellcode 202 gefundenen Benutzersubroutinen 204 erzeugt wurden. Bei der lib_sub_proc1 242 und der lib_sub_proc2 244 kann es sich um Standardbibliotheken handeln, die ausführbaren Code zum Durchführen der Bibliotheksubroutine 206 enthalten. Das heißt, die Standardbibliotheken können ausführbaren Code enthalten, der zuvor kompiliert wurde. Alternativ dazu oder zusätzlich kann der Kompilierer 226 auf der Grundlage der Benutzersubroutine 204 eine Bibliothek erzeugen. Um den Umfang des ausführbaren Codes 228 zu verringern, kann der Kompilierer 226 für jede der unterschiedlichen ausführbaren Versionen der optimierten Benutzersubroutine 204 eine separate Bibliothek erzeugen – d. h. die Bibliothek user_sub_proc1 238 und die Bibliothek user_sub_proc2 240. Dann fügt der Kompilierer 228 Bezüge auf diese Benutzerbibliotheken in den ausführbaren Code ein.
-
Nachdem der ausführbare Code 228 einem Prozessor zugewiesen wurde, löst der Verbinder die Bezüge 230, 232, 234 und 236 auf. In dieser Ausführungsform handelt es sich bei dem Verbinder um einen dynamischen Verbinder, mit dem das System das Auflösen der Bezüge 230, 232, 234 und 236 verschieben kann, bis der ausführbare Code 228 für das Ausführen zugewiesen wurde. Vor oder während des Ausführens des ausführbaren Codes 228 verwendet der Verbinder die Bezüge 230, 232, 234 und 236, um die zugehörige Bibliothek zu lokalisieren und diese Bibliothek in den Speicher zu laden. Die Bezüge werden aufgelöst, indem sichergestellt wird, dass der Prozessor die notwendigen Informationen besitzt, um die zugehörigen Bibliotheken 246 im Speicher zu lokalisieren.
-
Darüber hinaus kann der Verbinder das ID-Register verwenden, um den Architekturtyp des Prozessors zu ermitteln. Da dies bekannt ist, kann der Verbinder die in den Speicher zu ladenden Bibliotheken 246 selektiv auswählen und dabei die anderen Bibliotheken in der Speicherung (d. h. einem Festplattenlaufwerk) belassen. Wenn der Verbinder zum Beispiel feststellt, dass es sich bei dem Prozessor um den Prozessor 2 handelt, verschiebt der Verbinder nur die Bibliothek user_sub_proc2 240 und die Bibliothek lib_sub_proc2 244 in den Hauptspeicher. In einigen Ausführungsformen kann der Verbinder die Bezüge auch durch Ändern der Bezüge 230, 236 auf diese Bibliotheken innerhalb des ausführbaren Codes 228 so ändern, dass sie auf die Speicheradresse verweisen, unter der die Bibliotheken derzeit im Speicher gespeichert sind. Wenn somit der Prozessor den Bezug 230 oder 236 erreicht, während er den ausführbaren Code 228 ausführt, kann er den in der Bibliothek 240 oder 244 gefundenen Code vom Hauptspeicher holen und mit dem Ausführen des Stranges fortfahren.
-
Vorteilhafterweise kann dynamisches Verbinden den Umfang von in den Speicher 194 geladenem Code im Vergleich mit dem mittels statischem Verbinden gebildeten unabhängigen ausführbaren Code 210 verringern.
-
In einer Ausführungsform kann ein Hybridkompilierer 248 verwendet werden, um diesen Quellcode 202, Bibliotheken, auf die Bezug genommen wird, und Aufrufe externer Funktionen oder Variablen zu optimieren und kompilieren. Der Hybridkompilierer 250 erzeugt ausführbaren Code 250 (d. h. ein ausführbares Element oder einen Teil eines ausführbaren Elements) mithilfe der Prinzipien von sowohl statischem als auch dynamischem Verbinden. Der ausführbare Code 250 enthält unterschiedliche Versionen optimierten ausführbaren Codes – d. h. die Optionen 254 und 258 – sowie Bezüge auf Bibliotheken, die dynamisch aufgelöst werden, nachdem der ausführbare Code 250 einem Prozessor zugewiesen wurde.
-
Der statisch verbundene Teil des ausführbaren Codes 250 beinhaltet den Auswahlcode 252 und in der Option 254 und der Option 258 enthaltenen ausführbaren Code. Wie zuvor erläutert, weist der Auswahlcode 252 den Prozessor an, entweder den ausführbaren Code zum Ausführen der Benutzersubroutine auf Prozessor 1 (d. h. user_sub_on_proc1 256) oder den ausführbaren Code zum Ausführen der Benutzersubroutine für Prozessor 2 (d. h. user_sub_on_proc2 260) auszuwählen. Alternativ dazu kann der Lader 195 wie zuvor erläutert dieselbe Funktion durchführen, indem der Architekturtyp des Prozessors 192 ermittelt und die korrekte Version des optimierten Codes geladen wird.
-
Der dynamisch verbundene Teil des ausführbaren Codes 250 beinhaltet die Bezüge 262 und 264, die eine Verbindung mit den Bibliotheken 266 darstellen. Vor oder während des Ausführens kann der Verbinder 196 die Bezüge 262, 264 auflösen und die korrekte Standardbibliothek in den Speicher laden – d. h. entweder lib_sub_proc1 268 oder lib_sub_proc2 270. Es ist zu beachten, dass derselbe Prozess ebenso für benutzerspezifische Benutzerbibliotheken erfolgen kann.
-
Es ist zu beachten, dass der ausführbare Code 210, 228 oder 250 Code enthalten kann, der nicht speziell für einen spezifischen Prozessor optimiert ist. Zum Beispiel ist unter Umständen eine der Benutzersubroutinen 204 im Quellcode 202 nicht für eine bestimmte Architekturrealisierung optimiert. Somit muss ein Kompilierer nicht zwei unterschiedliche Versionen ausführbaren Codes für die Subroutine erzeugen, wenn der ausführbare Code statisch verbunden wurde. Stattdessen erzeugt der Kompilierer nur eine Version ausführbaren Codes auf der Grundlage der Benutzersubroutine. Diese Version kann direkt im ausführbaren Code 210, 228, 250 gespeichert werden. Gleichermaßen muss ein Kompilierer nur einen Bezug auf die externe Bibliothek einfügen, die den ausführbaren Code für diese Subroutine enthält, wenn die nicht optimierte Subroutine dynamisch verbunden wurde. Der Bezug kann eine Verbindung mit nur einer einzigen Bibliothek (oder Teil einer Bibliothek) bereitstellen, die den nicht optimierten ausführbaren Code enthält.
-
3 zeigt gemäß einer Ausführungsform der Erfindung einen Ablaufplan zum Ausführen von optimiertem Code, der statisch im System der 1A bis 1B verbunden ist. In Schritt 305 kann der Kompilierer 197 mittels statischer Verbindung einen ausführbaren Code erzeugen, der unabhängigen ausführbaren Code beinhaltet, der für eine Vielzahl unterschiedlicher Prozessorarchitekturrealisierungen optimiert ist. Somit beinhaltet in einer Ausführungsform der ausführbare Code unterschiedliche Versionen von optimiertem, kompiliertem Code, die demselben Quellcode entsprechen. Für Kompilierer, die eine oder mehrere Subroutinen innerhalb des Quellcodes optimieren, beinhaltet der sich ergebende ausführbare Code mindestens zwei unterschiedliche Versionen ausführbaren Codes für die Subroutine.
-
Darüber hinaus löst der Kompilierer 197 alle Bezüge oder Aufrufe einer Bibliothek oder anderen externen Funktion auf. Aufgrund dessen muss der Kompilierer 197 den Code, auf den Bezug genommen wird, in das unabhängige ausführbare Element einbringen. Das heißt, der Kompilierer 197 vereint den Code von der Bibliothek oder externen Funktion mit dem Quellcode und kompiliert den Code, um ein ausführbares Element auszubilden. Wenn der Code von der Bibliothek oder extern zuvor kompiliert wurde, kann der Kompilierer 197 diesen ausführbaren Code in das ausführbare Element einfügen. Wenn der Kompilierer 197 das Verbinden des Quellcodes mithilfe der Bezüge beendet hat, muss das sich ergebende ausführbare Element zum Ausführen nicht auf eine Bibliothek oder externe Funktion zugreifen.
-
In Schritt 310 kann das Betriebssystem 198 den Lader 195 anweisen, das ausführbare Element einem bestimmten Prozessor 192 auf dem Rechenknoten 190 zuzuweisen. Wie zuvor erwähnt, kann es sich bei dem ausführbaren Element um einen Strang handeln, der für einen Teil eines Jobs steht, der dem Mehrknotensystem 170 übermittelt wurde. Das Betriebssystem 198 kann den Lader 195 anweisen, das ausführbare Element dem Prozessor 192 zuzuweisen, der momentan beispielsweise die größte CPU-Verarbeitungsleistung zur Verfügung hat.
-
In Schritt 315 können der Lader 195 oder der ausführbare Code selbst ermitteln, welche Version der optimierten Subroutine auszuführen ist. In einer Ausführungsform kann der Kompilierer 197 Auswahlcode erzeugen und in den ausführbaren Code einfügen. Der Auswahlcode wird durch den Kompilierer 197 erzeugt, um zwischen den unterschiedlichen ausführbaren Versionen der optimierten Subroutine auszuwählen. Wenn der Auswahlcode ausgeführt wird, ermittelt er die Prozessor-ID, indem zum Beispiel auf das ID-Register 199 zugegriffen wird, und wählt die Version des Codes aus, die für die Architekturrealisierung des Prozessors optimiert ist. Die anderen Versionen werden vom Prozessor 192 nicht ausgeführt. Alternativ dazu kann der der Lader 195 die korrekte Version ermitteln und sicherstellen, dass der Prozessor nur diese Version der optimierten Funktion ausführt. In jeder Ausführungsform wird der korrekte optimierte Code jedoch ausgewählt, ohne dass ein Eingriff von einem Systemadministrator oder Programmierer erforderlich ist.
-
In Schritt 325 führt der Prozessor 192 den Codeteil aus, der für die bestimmte Architekturrealisierung des Prozessors 192 optimiert ist. Insbesondere werden die anderen Codeteile, die für andere Architekturrealisierungen optimiert sind, nicht ausgeführt. Der ausführbare Code kann jedoch andere Codeteile beinhalten, die ausgeführt werden, die nicht für eine bestimmte Prozessorarchitekturrealisierung optimiert wurden. Zum Beispiel kann der Kompilierer 197 nur diejenigen Subroutinen optimieren, die Bezug auf Subroutinen nehmen, die in Standardbibliotheken anzutreffen sind, wohingegen die Benutzersubroutinen nicht optimiert werden. Darüber hinaus kann das System Standardversionen von Subroutinen aufweisen, die im ausführbaren Element bei Abwesenheit von Realisierungen spezifischer Versionen verwendet werden. Dementsprechend weisen die nicht optimierten Benutzersubroutinen unter Umständen keine unterschiedlichen Versionen innerhalb des ausführbaren Codes auf
-
4 zeigt gemäß einer Ausführungsform der Erfindung einen Ablaufplan zum Ausführen von optimiertem Code, der dynamisch oder statisch im System der 1A bis 1B verbunden ist. In Schritt 405 erzeugt der Kompilierer 197 ein ausführbares Element, das dynamisch mit einer oder mehreren Bibliotheken verbunden ist. Wie zuvor erwähnt, kann der Kompilierer 197 Bezüge (d. h. Symbole oder Verbindungen) in das ausführbare Element einfügen, die auf eine Standardoder Benutzerbibliothek verweisen. Des Weiteren kann der Kompilierer 197 Verbindungen zu jeder der unterschiedlichen Versionen der Bibliothek einfügen, die den optimierten Code beinhalten. Alternativ dazu kann der Kompilierer 197 eine generische Verbindung zu einer oder mehreren Bibliotheken einfügen, welche die unterschiedlichen Versionen der optimierten Funktion beinhalten.
-
Darüber hinaus kann der Kompilierer 197 statisch verbundene Teile innerhalb des ausführbaren Elements erzeugen, die unterschiedliche ausführbare Versionen einer Subroutine beinhalten. Die korrekte Version der innerhalb des ausführbaren Codes gefundenen Subroutine kann ausgewählt werden, nachdem der ausführbare Code einem Prozessor zugewiesen wurde (d. h. während der Laufzeit).
-
In Schritt 410 kann das Betriebssystem 198 den Lader 195 anweisen, das ausführbare Element einem bestimmten Prozessor 192 auf dem Rechenknoten 190 zuzuweisen. Wie zuvor erwähnt, kann es sich bei dem ausführbaren Element um einen Strang handeln, der für einen Teil eines Jobs steht, der dem Mehrknotensystem 170 übermittelt wurde. Das Betriebssystem 198 kann den Lader 195 anweisen, das ausführbare Element dem Prozessor 192 zuzuweisen, der momentan beispielsweise die geringste CPU-Auslastung aufweist.
-
In Schritt 415 kann der statisch verbundene Teil des ausführbaren Elements ausgewählt werden, indem der Lader 195 verwendet wird oder Auswahlcode verwendet wird, der durch den Kompilierer 197 in den ausführbaren Code eingefügt wurde, was in Schritt 315 von 3 erläutert ist. Gleichermaßen kann der Verbinder 196 zudem die Architekturrealisierung des Prozessors identifizieren und das ausführbare Element dynamisch mit der Bibliothek verbinden, welche die optimierte, der Architekturrealisierung zugehörige Version beinhaltet.
-
Wenn der Kompilierer 197 in das ausführbare Element einen Bezug für jede optimierte Version der Subroutine einfügt, löst (d. h., er fügt eine Speicheradresse ein) der Verbinder 196 in Schritt 425 nur denjenigen Bezug auf, der eine Verbindung mit der korrekten optimierten Version darstellt. Wenn der Kompilierer 197 einen generischen Bezug in das ausführbare Element einfügt, kann der Verbinder 196 in einer anderen Ausführungsform die eine oder mehreren Bibliotheken analysieren und nur die Version der Subroutine in den Speicher 194 ziehen, die der Architekturrealisierung des zugewiesenen Prozessors entspricht. Der Verbinder 197 kann die anderen Versionen der Subroutine in der Speicherung belassen. Der Verbinder 196 löst dann den auf die in den Speicher 194 geladene Bibliothek verweisenden Bezug auf.
-
In Schritt 430 beginnt der zugewiesene Prozessor 192, den ausführbaren Code auszuführen. Sobald der Prozessor 192 dem aufgelösten Bezug zugehörigen Objektcode ausführt, kann der Prozessor 192 beginnen, den Objektcode auszuführen, der in der durch den Verbinder 196 in den Speicher 194 geladenen Bibliothek gefunden wurde.
-
Eine Beispielkonfiguration des Mehrknotensystems
-
5 veranschaulicht einen 4 × 4 × 4-Torus 501 von Rechenknoten 190, bei dem die inneren Knoten zur Klarheit weggelassen wurden. Obwohl 5 einen 4 × 4 × 4-Torus mit 64 Knoten zeigt, ist für den Fachmann ersichtlich, dass die tatsächliche Anzahl von Rechenknoten in einem parallelen Computersystem üblicherweise viel höher liegt, zum Beispiel umfasst ein Blue Gene/L-System 65.536 Knoten. Jeder Rechenknoten im Torus 501 enthält einen Satz von sechs Knoten-zu-Knoten-Datenübertragungsverbindungen 501A bis F, mit denen jeder Rechenknoten im Torus 501 mit seinen sechs unmittelbar benachbarten Knoten, jeweils zwei Knoten in x-, y- und z-Richtung, Daten austauschen kann. In einer Ausführungsform kann das Mehrknotensystem 170 ein separates Torus-Netzwerk für jeden auf dem System 170 ausgeführten Job einrichten. Alternativ dazu können alle Rechenknoten verbunden sein, um den Torus auszubilden.
-
Der hierin verwendete Begriff „Torus” schließt jedes regelmäßige Muster von Knoten und Datenübertragungspfaden zwischen den Knoten in mehr als einer Richtung derart ein, dass jeder Knoten einen definierten Satz von Nachbarn aufweist und es für jeden gegebenen Knoten möglich ist, den Satz von Nachbarn dieses Knotens zu bestimmen. Ein „Nachbar” eines gegebenen Knoten ist jeder Knoten, der mit dem gegebenen Knoten durch einen direkten Datenübertragungspfad zwischen Knoten verbunden ist – d. h. einen Pfad, der keinen weiteren Knoten durchlaufen muss. Die Rechenknoten können in einem dreidimensionalen Torus 501 wie in 5 gezeigt verbunden sein, können jedoch auch so eingerichtet sein, dass sie mehr oder weniger Dimensionen aufweisen. Zudem ist es nicht notwendig, dass es sich bei den Nachbarn eines gegebenen Knotens um die dem gegebenen Knoten räumlich am nächsten liegenden Knoten handelt, obwohl es allgemein wünschenswert ist, die Knoten soweit möglich in derartiger Weise anzuordnen.
-
In einer Ausführungsform bilden die Rechenknoten in einer der x-, y- oder z-Richtungen einen Torus in dieser Richtung aus, da sie von den Punkt-zu-Punkt-Datenübertragungsverbindung logisch umlaufen werden. Dies ist zum Beispiel in 5 durch Verbindungen 505D, 505E und 505F dargestellt, die von einem letzten Knoten in den x-, y- und z-Richtungen zu einem ersten Knoten zurücklaufen. Obwohl somit ein Knoten 510 an einer „Ecke” des Torus angeordnet zu sein scheint, verbinden die Knoten-zu-Knoten-Verbindungen 505A bis F den Knoten 510 mit Knoten 511, 512 und 513 in den x-, y- und z-Richtungen des Torus 501.
-
Fazit
-
Ein Kompilierer kann Quellcode und alle Bibliotheken, auf die Bezug genommen wird, optimieren, um auf einer Vielzahl unterschiedlicher Prozessorarchitekturrealisierungen ausgeführt werden zu können. Wenn zum Beispiel ein Rechenknoten drei unterschiedliche Typen von Prozessoren mit drei unterschiedlichen Architekturrealisierungen aufweist, kann der Kompilierer den Quellcode kompilieren und drei Objektcodeversionen erzeugen, wobei jede Version für einen der drei unterschiedlichen Prozessortypen optimiert ist. Nach dem Kompilieren des Quellcodes kann der sich ergebende ausführbare Code die notwendigen Informationen zum Auswählen zwischen den drei Versionen enthalten. Wenn zum Beispiel ein Programmlader dem Prozessor den ausführbaren Code zuweist, ermittelt das System den Typ des Prozessors und stellt sicher, dass nur die diesem Typ entsprechende optimierte Version ausgeführt wird. Somit kann das Betriebssystem ohne Weiteres den ausführbaren Code jedem beliebigen Prozessor auf der Grundlage von zum Beispiel der Leistungsfähigkeit oder dem Status des Prozessors zuweisen und nach wie vor die Vorteile des Ausführens von Code nutzen, der für jeden dem ausführbaren Code zugewiesenen Prozessor optimiert ist.
-
Der Ablaufplan und die Blockschaubilder in den Figuren veranschaulichen die Architektur, Funktionalität und die Arbeitsweise möglicher Realisierungen von Systemen, Verfahren und Computerprogrammprodukten gemäß verschiedenen Ausführungsformen der vorliegenden Erfindung. In dieser Hinsicht kann jeder Block im Ablaufplan oder den Blockschaubildern für ein Modul, ein Segment oder einen Codeabschnitt stehen, der eine oder mehrere ausführbare Anweisungen zum Realisieren der angegebenen logischen Funktion oder Funktionen aufweist. Es soll zudem angemerkt werden, dass bei einigen alternativen Realisierungen die im Block angegebenen Funktionen in anderer Reihenfolge als der in den Figuren angegebenen auftreten können. Zum Beispiel können zwei aufeinander folgend abgebildete Blöcke tatsächlich im Wesentlichen gleichzeitig ausgeführt werden, oder die Blöcke können manchmal abhängig von der betreffenden Funktionalität in umgekehrter Reihenfolge ausgeführt werden. Es wird ebenfalls angemerkt, dass jeder Block der Blockschaubilder und/oder Abbildung von Ablaufplänen und Kombinationen von Blöcken in den Blockschaubildern und/oder der Abbildung von Ablaufplänen durch zweckbestimmte hardwaregestützte Systeme oder Kombinationen von zweckbestimmter Hardware und Computeranweisungen realisiert werden kann, welche die angegebenen Funktionen oder Handlungen durchführen.
-
Während das Vorhergehende auf Ausführungsformen der vorliegenden Erfindung gerichtet ist, können andere und weitere Ausführungsformen der Erfindung entwickelt werden, ohne von deren grundlegendem Umfang abzuweichen, der durch die folgenden Ansprüche bestimmt wird.