DE69615445T2 - Kompilierer zur Verbesserung der Leistung von Datencachespeichern - Google Patents

Kompilierer zur Verbesserung der Leistung von Datencachespeichern

Info

Publication number
DE69615445T2
DE69615445T2 DE69615445T DE69615445T DE69615445T2 DE 69615445 T2 DE69615445 T2 DE 69615445T2 DE 69615445 T DE69615445 T DE 69615445T DE 69615445 T DE69615445 T DE 69615445T DE 69615445 T2 DE69615445 T2 DE 69615445T2
Authority
DE
Germany
Prior art keywords
prefetch
loop
memory
instructions
cluster
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
DE69615445T
Other languages
English (en)
Other versions
DE69615445D1 (de
Inventor
Vatsa Santhanam
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Hewlett Packard Development Co LP
Original Assignee
Hewlett Packard Co
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Hewlett Packard Co filed Critical Hewlett Packard Co
Application granted granted Critical
Publication of DE69615445D1 publication Critical patent/DE69615445D1/de
Publication of DE69615445T2 publication Critical patent/DE69615445T2/de
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation
    • G06F8/4441Reducing the execution time required by the program code
    • G06F8/4442Reducing the number of cache misses; Data prefetching
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/30003Arrangements for executing specific machine instructions
    • G06F9/3004Arrangements for executing specific machine instructions to perform operations on memory
    • G06F9/30047Prefetch instructions; cache control instructions
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/30Arrangements for executing machine instructions, e.g. instruction decode
    • G06F9/38Concurrent instruction execution, e.g. pipeline or look ahead
    • G06F9/3824Operand accessing
    • G06F9/383Operand prefetching

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • General Engineering & Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Memory System Of A Hierarchy Structure (AREA)
  • Devices For Executing Special Programs (AREA)

Description

  • Diese Erfindung bezieht sich auf Techniken zum Reduzieren von Datencachespeicher-Mehraufwand bei einem Computersystem. Insbesondere bezieht sich die Erfindung auf Kompilierer-bezogene Techniken, die zum Reduzieren von Datencachespeicher-Mehraufwand nützlich sind.
  • Datencachespeicherfehlschläge (weiter unten detaillierter beschrieben) können für einen wesentlichen Teil der Ausführungszeit eines Anwendungsprogramms bei modernen Prozessoren verantwortlich sein. Dies trifft insbesondere im Fall wissenschaftlicher Anwendungen zu, die große Datenstrukturen verarbeiten, die auf Hochfrequenzprozessoren mit langen Speicherlatenzzeitzeiten laufen. Mit zunehmender Fehlanpassung zwischen Prozessor und Speicher ist der hohe Mehraufwand von Cachespeicherfehlschlägen eine dominante Einschränkung der Leistungsfähigkeit von Mikroprozessen geworden und ist dies auch weiterhin. Erhöhen der Cachespeichergröße ist eine Möglichkeit, um Cachfehlschläge zu reduzieren. Da jedoch die Größe vieler numerischer Anwendungen von Generation zu Generation ebenfalls schnell wächst, könnte der Cachespeicher der ersten Ebene nicht immer groß genug sein, um kritische Arbeitssätze zu erfassen.
  • Die meisten modernen Computersysteme verwenden solche Cachespeicher, um den Abstand zwischen Speicher- und Prozessorgeschwindigkeit zu überbrücken. Trotz hoher Cachespeichertrefferraten können die Kosten von Cachespeicherfehlschlägen bei Hochfrequenzprozessoren die Laufzeitleistungsfähigkeit wesentlich verschlechtern. Um diesen Punkt darzustellen, wurde ein mögliches Szenario vorgeschlagen, bei dem eine Cachefehlschlagstrafe 100 Prozessorzyklen beträgt, und alle vier Zyklen eine Datenreferenz auftritt. Siehe beispielsweise Alexander C. Klaiber, Henry M. Levy, An Architecture for Software-Controlled Data Prefetching, Proceedings of the 18th Annual International Symposium on Computer Architecture, Mai 1991. Selbst wenn eine Cachespeichertrefferrate von 99% angenommen wird, ist der Prozessor 20% der Zeit für den Speicher blockiert.
  • Ein Weg, um den hohen Mehraufwand von Datencachespeicherfehlschlägen zu lindern, ist es, das Abrufen von Daten vom Speicher auf den Datencachespeicher mit anderen nützlichen Berechnungen zu überlappen. Bestimmte hochleistungsfähige superskalare Mikroprozessoren sind in der Lage, einen gewissen Grad von Überlappung zwischen einer Datencachespeicherfehlschlaghandhabung und einer Prozessorberechnung automatisch zu erreichen, durch eine Befehlausführung außerhalb der Reihenfolge, die durch Befehlswarteschlangen ermöglicht wird, die in der Lage ist, umbenannte Registerergebnisse zu halten, in Verbindung mit einem Geteilte- Transaktion-Speicherbus (wie z.B. solche Mikroprozessoren wie der Silicon Graphics T5, Hewlett-Packard PA8000, und Sun Ultrasparc). Der Grad an Überlappung, der typischerweise erzielt wird, ist jedoch nicht ausreichend, um eine externe Datencachespeicherfehlschlaglatenzzeit abzudecken.
  • Einige dieser Mikroprozessoren unterstützen explizite Datenvorausabrufbefehle, die verwendet werden können, um den hohen Mehraufwand von Datencachespeicherfehlschlägen effektiver zu reduzieren. Solche Befehle sind typischerweise definiert, um eine Datencachespeicherfehlschlaghandhabung auszulösen, ohne die Befehlsausführung aufzuhalten, bis die referenzierten Daten von dem Speicher wiedergewonnen werden.
  • Durch Einfügen expliziter Datencachespeichervorausabrufbefehle in den Codestrom kann ein Kompilierer dazu beitragen, die hohen Kosten von Datencachespeicherfehlschlägen zu verbessern. Dieser Lösungsansatz muß jedoch wohl überlegt implementiert werden, da explizite Cachespeichervorausabrufbefehle allgemein die dynamische Pfadlänge einer Anwendung erhöhen, und der hinzugefügte Mehraufwand kann nicht durch eine entsprechende Verringerung bei dem Datencachespeicherfehlschlag-Mehraufwand versetzt werden.
  • Es gibt viel veröffentlichte Literatur über Cachespeicherentwurfnachteile und Hardwareansätze, um die Cachespeicherleistungsfähigkeit zu verbessern. Vergleichsweise gibt es jedoch sehr viel weniger Literatur über das Verbessern der Cachespeicherleistungsfähigkeit durch softwaregesteuerte aktive Cachespeicherverwaltung. Die wenigen Abhandlungen, die softwaregesteuertes Datenvorausabrufen zum Verbessern der Cachespeicherleistungsfähigkeit erörtern, umfassen: Todd C. Mowry, Monica S. Lam, Anoop Gupta, Design and Evaluation of a Kompiler Algorithm for Prefetching, Proceedings of the 5th International Conference on Architectural Support for Programming Languages and Operating Systems, Oktober 1992; Alexander C. Klaiber, Henry M. Levy, An Architecture for Software-Controlled Data Prefetching, Proceedings of the 18th Annual International Symposium on Computer Architecture, Mai 1991 (ein Lösungsansatz auf der Basis von Handanalyse); und Software Prefetching, David Callahan, Ken Kennedy, Allan Porterfield, Proceedings of the 4th International Conference on Architectural Support for Programming Languages and Operating Systems, April 1991 (wo für jede Schleifenkernspeicherreferenz ein Vorausabrufbefehl hinzugefügt wird, ohne Cachespeicherzeilenwiederverwendung zu betrachten oder auszunützen, so daß es keine Selektivität gibt; und wo die Vorausabrufeinfügung auf der Quellencodeebene durchgeführt wird, so daß es wenig Integration mit anderen Kompiliereroptimierungsphasen gibt; da die Analyse auf der Quellencodeebene durchgeführt wird, ist es außerdem schwierig, den Vorausabruf-Iterationsabstand (PFID = prefetch iteration distance) zu schätzen, d.h. der verwendete PFID ist immer eine Schleifeniteration, die eventuell nicht ausreicht, um die gesamte Cachespeicherfehlschlaglatenzzeit zu verstecken).
  • Diese Abhandlungen konzentrieren sich auf explizite Vorausabrufungen für Variablen mit Index, die in Schleifen referenziert werden. Dieselben erörtern nicht die Einfügung expliziter Vorausabrufbefehle in Geradzeilencode für skalare oder indirekte Speicherreferenzen. Ferner wird im allgemeinen angenommen, daß die Arrays, die von Interesse sind, alle auf Cachespeicherzeilengrenzen ausgerichtet sind.
  • Es gibt einige allgemeinen Beobachtungen, die mehr oder wenig häufig in den verschiedenen Studien über Softwaregesteuertes Datenvorausabrufen vorkommen. Eine solche Beobachtung ist, daß Datenvorausabrufen nicht umsonst zu haben ist. Genauer gesagt, explizite Vorausabrufungen verbrauchen Befehlsausgabebandbreite. Zusätzlich zu dem Vorausabrufbefehl selber werden typischerweise einer oder mehrere Befehle benötigt, um die Adresse der Speicherposition, die vorausabgerufen werden soll, zu berechnen. Das Wiederverwerten der berechneten Vorausabrufadresse für die tatsächliche Referenz kann die Belegung von Registern für erweiterte Lebensdauern umfassen. Der erhöhte Registerdruck zu der Einführung von Überlaufcode in teure Schleifen führen. Dies kann die erwarteten Leistungsfähigkeitsgewinne aufgrund des Vorausabrufens versetzen.
  • Ein einfache Vorausabrufstrategie, wie z.B. diejenige, die von David Callahan, Ken Kennedy, Allan Porterfield, Software Prefetching, Proceedings of the 4th International Conference on Architectural Support for Programming Languages and Operating Systems, April 1991, vorgeschlagen wurde, kann die Anzahl der ausgeführten Befehle durch mehrere Vorausabrufanforderungen für Zeilen, die sich bereits in dem Datencachespeicher befinden, kostspielig erhöhen.
  • Eine weitere wichtige Überlegung, die von den unterschiedlichen Abhandlungen über softwaregesteuertes Datenvorausabrufen angeführt wird, ist das tatsächliche Plazieren der Vorausabrufbefehle. Falls ein Vorausabrufbefehl zeitmäßig zu nahe zu der Speicherreferenz ausgegeben wird, welche die auf die vorausabgerufenen Daten zugreifen muß, können die vorausabgerufenen Daten nicht rechtzeitig verfügbar sein, um ein CPU-Anhalten zu verhindern. Falls dagegen der Vorausabrufbefehl zu früh ausgegeben wird, besteht die Möglichkeit, daß die vorausabgerufene Zeile verfrüht von dem Cachespeicher verschoben wird.
  • Todd C. Mowry, Monica S. Lam, Anoop Gupta, Design and Evaluation of a Kompiler Algorithm for Prefetching, Proceedings of the 5th International Conference on Architectural Support for Programming Languages and Operating Systems, Oktober 1992, erörtern die Idee, ein Vorausabrufprädikat und die führende Referenz unter meheren Referenzen auf ein Array zu identifizieren, um ein selektives Vorausabrufen zu ermöglichen. Diese Abhandlung erörtert außerdem die Wechselwirkung von Datenvorausabrufen mit anderen Kompilierer- Transformationen, insbesondere Cachespeicherblockieren und Softwarepipelineverarbeitung. Der offenbarte Vorausabrufalgorithmus ist beim Reduzieren eines expliziten Datenvorausabrufmehraufwands wirksam. Eine Unzulänglichkeit bei diesem Lösungsansatz liegt darin, daß er sich auf Wiederverwendung und Positionsanalyse verläßt, die sehr komplex ist. Die Analyse wird im Kontext eines Opimierers auf hoher Ebene durchgeführt, was es schwierig macht, den Vorausabruf- Iterationsabstand zu schätzen, da die Effekte von in Verarbeitungsrichtung nachgeordneten Kompiliererkomponenten (z. B. Codegenerator und Optimierer auf niedriger Ebene) auf dem Schleifenkern unbekannt sind. Es ist außerdem unklar, wie die Cachespeicherzeilenausrichtung vorausabgerufener Datenstrukturen gebildet wird, wenn Speicherschritte größer sind als die Cachespeicherzeilengröße. Außerdem ist es unklar, ob für bestimmte Typen von Datenwiederverwendungsstrukturen unnötige Vorausabrufungen eingefügt werden. Beispielsweise kann der offenbarte Algorithmus für das folgende C-Codebruchteil in der Tat drei Vorausabrufungen einfügen, wenn zwei ausreichend wären, um vollständige Fehlschlagabdeckung sicherzustellen.
  • Computer Architecture News, Bd. 22, Nr. 2, 1. April 1994, Seiten 223-232, Chen et al "A Performance Study of Software and Hardware Data Prefetching Schemes" erörtert das Thema der Cachespeicherverunreinigung aufgrund des Datencachespeichervorausabrufens und rät zu der Verwendung einer Hardwarestruktur, die als ein "Vorausabrufpuffer" bezeichnet wird. Dieses Dokument implementiert einen Datenvorausabrufalgorithmus in einem Kompilierer, der auf der Assemblierungsebene wirkt, und Datenvorausabrufbefehle in Schleifen von Anwendungen einfügt.
  • Proceedings of the Annual International Symposium on Micro- Architect, Austin, 1.-3. Dez. 1993, Nr. Symp. 26, 1. Dezember 1993, Institute of Electrical and Electronic Engineers, Seiten 139-152, Abraham et al "Predictability of Load/Store Instruction Latencies" erörtert Cachespeichersteuerungsbefehle zum ausgewählten Vorausabrufen von Daten, die durch eine kleine Anzahl von Befehlen referenziert werden, die durch Profilieren identifiziert werden, um die Gesamtfehlschlagrate zu reduzieren.
  • Proceedings of the Region 10 International Conference, 22. August 1994, Seiten 274-278, Chi et al "Kompiler Driven Data Cachespeicher Prefetching for High Performance Computers" erörtert ein Vorausabrufschema, das eingebettetes Datenvorausabrufen genannt wird, um Arrayreferenzen mit konstanten Schritten vorausabzurufen.
  • Gemäß einem ersten Aspekt der vorliegenden Erfindung ist ein System geschaffen, das eine Computereinrichtung umfaßt, auf der ein Kompiliererprogramm läuft, wie es in Anspruch 1 definiert ist.
  • Gemäß einem zweiten Aspekt der vorliegenden Erfindung ist ein Verfahren zum Mildern oder Eliminieren von Cachespeicherfehlschlägen in einem Optimierer auf niedriger Ebene geschaffen, wie es in Anspruch 5 definiert ist.
  • Man nehme an, daß ein Zielprozessor einen Datencachespeicherzeilenvorausabrufbefehl mit den folgenden Charakteristika unterstützt:
  • - Er ermöglicht es, daß eine Speicheradresse spezifiziert wird, beinahe wie bei einem gewöhnlichen Lade- oder Speicherbefehl;
  • - falls der Speicher, der durch den Vorausabrufbefehl referenziert wird, in dem Datencachespeicher nicht gefunden wird, bewirkt der Prozessor, daß die referenzierte Speicherposition von niedrigeren Ebenen der Speicherhierarchie abgerufen wird, ohne die Ausführung anderer Befehle in den Ausführungspipelines des Prozessors zu blockieren; und
  • - der Prozessor meldet keine Ausnahme, selbst wenn die Speicheradresse, die durch einen Vorausabrufbefehl spezifiziert wird, ungültig ist.
  • Die vorliegende Erfindung schafft einen neuen Kompilierer für einen solchen Prozessor, der wirksame Einfügung von expliziten Datenvorausabrufbefehlen in Schleifen innerhalb von Anwendungsprogrammen ermöglicht. Der Kompilierer verwendet einfache Indexausdruckanalyse, um Datenvorausabrufanforderungen zu bestimmen. Die Analyse und die explizite Datencachespeichervorausabrufbefehleinfügung werden durch den Kompilierer in einem Optimierer auf Maschinenbefehlebene durchgeführt, um Zugriff auf genauere erwartete Schleifeniterationslatenzzeitinformationen zu erhalten.
  • Eine solche Vorausabrufbefehleinfügungsstrategie toleriert eine schlechteste anzunehmende Ausrichtung von Benutzerdatenstrukturen bezüglich Datencachespeicherzeilen. Ausführungsprofile von vorhergehenden Abläufen einer Anwendung werden bei der Einfügung von Vorausabrufbefehlen in Schleifen mit innerem Steuerungsfluß ausgenutzt. Cachespeicherzeilenwiederverwendungsstrukturen über Schleifeniterationen werden erkannt, um unnötige Vorausabrufbefehle zu eliminieren. Der Vorausabrufeinfügungsalgorithmus ist mit anderen Optimierungsphasen auf niedriger Ebene integriert, wie z. B. dem Schleifenabrollen, der Registerneuzuordnung und der Befehlsplanung.
  • Ein alternatives Ausführungsbeispiel des Kompilierers beschränkt die Einfügung expliziter Vorausabrufbefehle auf die Situationen, in denen die untere Grenze auf der erreichbaren Schleifeniterationslatenzzeit als Folge der Einfügung wahrscheinlich nicht erhöht wird.
  • Die Erfindung wird nun mit Referenz auf beispielhafte Ausführungsbeispiele erklärt, die in den beiliegenden Zeichnungen dargestellt sind.
  • Fig. 1 ist ein schematisches Blockdiagramm einer Uniprozessorcomputerarchitektur, die einen Prozessorcachespeicher umfaßt;
  • Fig. 2 ist ein schematisches Blockdiagramm eines modernen Softwarekompilierers;
  • Fig. 3 ist eine schematische Darstellung einer Schleife;
  • Fig. 4 ist eine schematische Abbildung eines direkt abgebildeten Datencachespeichers;
  • Fig. 5 ist eine schematische Darstellung einer Schleife, die einen Vorausabrufbefehl umfaßt;
  • Figur.6 ist eine schematische Darstellung einer Schleife, die viermal abgerollt wurde;
  • Fig. 7 ist eine schematische Darstellung einer abgewikkelten Schleife, die einen Vorausabrufbefehl umfaßt;
  • Fig. 8 ist ein Blockdiagramm, das einen Optimierer auf niedriger Ebene für einen Kompilierer zeigt, der einen Vorausabruftreiber gemäß der Erfindung umfaßt;
  • Fig. 9 ist ein Blockdiagramm eines Vorausabruftreibers gemäß der Erfindung;
  • Fig. 10 ist ein Blockdiagramm eines Schleifenkernanalysemoduls gemäß der Erfindung;
  • Fig. 11 ist ein Blockdiagramm eines Moduls, das verwendet wird, um Vorausabrufbefehle für eine Äquivalenzklasse gemäß der Erfindung zu berechnen; und
  • Fig. 12 ist ein Blockdiagramm eines Moduls, das einen Großschrittclusteridentifizierer an eine Äquivalenzklasse gemäß der Erfindung anlegt.
  • Die Erfindung schafft einen neuen Kompilierer, der wirksame Einfügung von expliziten Datenvorausabrufbefehlen in Schleifen innerhalb von Anwendungen ermöglicht. Fig. 1 ist ein schematisches Blockdiagramm einer Uniprozessorcomputerarchitektur 10, die einen Prozessorcachespeicher umfaßt. In der Figur umfaßt ein Prozessor 11 einen Cachespeicher 12, der mit einem Systembus 15 in Kommunikation ist. Ein Systemspeicher 13 und eines oder mehrere I/O-Geräte 14 sind ebenfalls in Kommunikation mit dem Systembus.
  • Fig. 2 ist ein schematisches Blockdiagramm eines Softwarekompilierers 20, der beispielsweise in Verbindung mit der in Fig. 1 gezeigten Computerarchitektur 10 verwendet werden kann. Die Front-End-Komponente 21 des Kompilierers liest eine Quellencodedatei 100 und übersetzt sie in eine Zwischendarstellung auf hoher Ebene (HLIR = high level intermediate representation) 110. Ein Optimierer auf hoher Ebene 22 optimiert die Zwischendarstellung auf hoher Ebene 110 in eine effizientere Form. Ein Codegenerator 23 übersetzt die optimierte Zwischendarstellung auf hoher Ebene in eine Zwischendarstellung auf niedriger Ebene (LLIR = low level intermediate re presentation) 120. Der Optimierer auf niedriger Ebene 24 wandelt die Zwischendarstellung auf niedriger Ebene 120 in eine effizientere (maschinenausführbare) Form um. Schließlich schreibt ein Objektdateigenerator 25 die optimierte Zwischendarstellung auf niedriger Ebene in eine Objektdatei 141 aus. Die Objektdatei 141 wird zusammen mit anderen Objektdateien 124 durch einen Linker 26 verarbeitet, um eine ausführbare Datei 150 zu erzeugen, die auf dem Computer 10 laufen kann. Bei der hierin beschriebenen Erfindung wird angenommen, daß die ausführbare Datei 150 durch den Kompilierer 20 und Linker 26 ausgeführt werden kann, so daß, wenn dieselbe auf dem Computer 10 läuft, ein Ausführungsprofil 160 erzeugt werden kann, welches dann durch den Optimierer auf niedriger Ebene 24 verwendet werden kann, um die Zwischendarstellung auf niedriger Ebene 120 besser zu optimieren. Der Kompilierer 20 wird unten detaillierter erörtert.
  • Im Gegensatz zu vorhergehenden Lösungsansätzen zu dem oben erörterten Cachespeicherfehlschlagproblem (siehe Todd C. Mowry, Tolerating Latency Through Software-Controlled Data Prefetching, PhD Thesis, Dept. of Electrical Engineering, Stanford University, März 1994; D. Callahan, K. Kennedy, A. Porterfield, Software Prefetching, Proceedings of the Fourth International Conference on Architectural Support for Programming Languages and Operating Systems, S. 40-52, April 1991; und W.Y. Chen, S.A. Mahlke, P.P. Chang, W. W. Hwu, Data access microarchitectures for superscalar processors with kompilerassisted data prefetching, Proceedings of Microcomputing 24, 1991) weist der neue Kompilierer die folgenden einzigartigen Attribute auf:
  • - Eine einfache Indexausdruckanalyse wird verwendet, um Datenvorausabruferfordernisse zu bestimmen, im Gegensatz zu einer hoch entwickelten Wiederverwendungs- /Abhängigkeitsanalyse.
  • - Eine Indexausdruckanalyse und explizite Datencachespeichervorausabrufbefehleingabe werden durch den Kompilierer in einem Optimierer auf niederiger Ebene, d.h. Maschinenbefehlebene, durchgeführt. Ein grundsätzlicher Vorteil dieses Lösungsansatzes ist Zugang zu genauerer erwarteter Schleifeniterationslatenzzeitinformation.
  • - Die Vorausabrufbefehleinfügungsstrategie toleriert eine schlechteste anzunehmende Ausrichtung von Benutzerdatenstrukturen bezüglich Datencachespeicherzeilen.
  • - Ausführungsprofile von vorhergehenden Abläufen einer Anwendung werden bei der Einfügung von Vorausabrufbefehlen in Schleifen mit internem Steuerungsfluß ausgenutzt.
  • - Cachespeicherzeilenwiederverwendungsstrukturen über Schleifeniterationen werden erkannt, um unnötige Vorausabrufbefehle zu eliminieren.
  • - Der Vorausabrufeinfügungsalgorithmus ist mit anderen Optimierungsphasen auf niedriger Ebene integriert, wie z.B. Schleifenaufrollen, Registerneuzuordnung und Befehlsplanung.
  • Ein alternatives Ausführungsbeispiel des neuen Kompilierers beschränkt außerdem die Einfügung expliziter Vorausabrufbefehle auf die Situationen, bei denen die untere Grenze der erhältlichen Schleifeniterationslatenzzeit als Folge der Einfügung wahrscheinlich nicht erhöht wird.
  • Der neue Kompilierer erzielt wesentliche Leistungsfähigkeitsverbesserungen für einige Industriestandardleistungsfähigkeitsbenchmarks bei Simulationen des PA-8000 Prozessors der Hewlett-Packard-Company (Palo Alto, Kalifornien).
  • Die folgende Erörterung erklärt den Kompiliererbetrieb im Zusammenhang einer Schleife innerhalb eines Anwendungsprogramms. Schleifen werden leicht erkannt als eine Sequenz des Codes, der einige Male wiederholt ausgeführt wird. Die Sequenz solcher Operationen ist vorhersagbar, da der gleiche Satz von Operationen für jede Iteration der Schleife wiederholt wird. Bei einem Anwendungsprogramm ist es allgemeine Praxis, eine Indexvariable für jede Schleife zu erhalten, die mit einem Anfangswert versehen ist, und die um einen konstanten Betrag für jede Schleifeniteration inkrementiert wird, bis die Indexvariable einen Endwert erreicht. Die Indexvariable wird oft verwendet, um Elemente eines Arrays anzusteuern, die einer regelmäßigen Sequenz von Speicherpositionen entsprechen. Solche Arrayreferenzen durch eine Schleife bilden einen wesentlichen Teil von Cachespeicherfehlschlägen bei wissenschaftlichen Anwendungen.
  • Bei dem Kompilierer wurde herausgefunden, daß sich die Komponente des Optimierers auf niedriger Ebene eines Kompilierers in einer guten Position befindet, um die Anzahl von Zyklen abzuleiten, die für einen Codeabschnitt erforderlich sind, der wiederholt ausgeführt wird. Wie oben ausgeführt, ist das Konzept des Vorausabrufens nicht neu.
  • Trotzdem ist es hilfreich, das Vorausabrufen an diesem Punkt zu erklären. Man nehme beispielsweise an, daß die Zeit, die erforderlich ist, um ein Datenelement von dem Hauptspeicher zu dem Cachespeicher zurückzubekommen, 100 Zyklen beträgt, während dieser Zeit muß der Prozessor ungenutzt warten, bevor er die Daten bearbeiten kann. Um das Verschwenden ungenutzter Prozessorzyklen aufgrund von Datencachespeicherfehlschlägen zu vermeiden, ist es wünschenswert, die Rückgewinnung von Daten, die vermutlich nicht in dem Cachespeicher gefunden werden, auszulösen, bevor solche Daten von dem Prozessor benötigt werden. Der Kompilierer kann vorhersagen, welche Daten im Voraus benötigt werden für Schleifen, die regelmäßig auf Arrayelemente zugreifen. Der Kompilierer kann dann Vorausabrufbefehle in Schleifen eingeben, so daß Arrayelemente, die vermutlich in zukünftigen Schleifeniterationen benötigt werden, vor der Zeit von dem Speicher zurückgewonnen werden. Idealerweise ist die Anzahl von Vorausiterationen, mit denen Arrayelemente vorausabgerufen werden derart, daß zu dem Zeitpunkt, zu dem das Arrayelement von dem Prozessor wirklich erforderlich ist, das Arrayelement von dem Speicher zurückgewonnen und in dem Datencachespeicher plaziert ist (falls es dort nicht von Anfang an war).
  • Bei herkömmlichen Lösungsansätzen zum Vorausabrufen ist die Cachespeicherausrichtung ein Problem. Ein weiteres Problem ist der Mehraufwand des Vorausabrufbefehls selbst. Dies sind sehr wichtige Probleme. Laufzeitarraydimensionierung ist noch ein weiteres Problem, das angesprochen werden muß.
  • In Fig. 3 ist beispielsweise eine Schleife gezeigt, die eine Schleifenausführungszeit von 10 Zyklen aufweist und die sich 100 mal wiederholt, wobei sie bei jeder Iteration auf ein 8-Byte-Arrayelement zugreift. Falls keine Cachespeicherfehlschläge auftreten, beträgt die Gesamtschleifenausführungszeit 1000 Zyklen. In Fig. 4 ist ein direkt abgebildeter Datencachespeicher gezeigt, bei dem die Cachespeicherzeilengröße 32 Byte beträgt, wobei jede Zeile in der Lage ist, vier zusammenhängende 8-Byte-Arrayelemente zu halten. Für die Schleife von Fig. 3 wird angenommen, daß bei jeder vierte Iteration ein Cachespeicherfehlschlag auftritt (bei jeder Cachespeicherzeilenkreuzung), was bedeutet, daß für die gesamte Schleife 25 Datencachespeicherfehlschläge auftreten werden. Falls es 40 Zyklen benötigt, um jeden Cachespeicherfehlschlag zu bedienen, wird die Gesamtschleifenausführungszeit 2000 Zyklen, d.h. 1000 Zyklen lediglich zum Ausführen der Schleifenbefehle + 25 · 40 Zyklen, oder weitere 1000 Zyklen für die Cachespeicherfehlschläge.
  • Falls bekannte Vorausabruftechniken verwendet werden, können für das Beispiel der Fig. 3 und 4 Cachespeicherfehlschläge bedeckt werden, wenn ein Vorausabrufabstand von 4 gewählt wird. In Fig. 5 ist ein Vorausabrufbefehl gezeigt, der in die Schleife von Fig. 3 eingefügt ist. Wie gesehen werden kann, kann die Verwendung eines Vorausabrufbefehls die meisten Cachespeicherfehlschläge eliminieren, wodurch wesentliche Ausführungszeit gespart wird. Ein Vorausabrufbefehl erfordert jedoch Ausführungszeit. Bei diesem Beispiel erfordert jede Iteration der Schleife einen Vorausabrufbefehl, von dem angenommen werden kann, daß er einen Extrazyklus benötigt. Daher müssen für eine Schleife, die sich 100 mal wiederholt, zu der Ausführungszeit 100 Zyklen hinzugefügt werden für das Vorausabrufen.
  • Zusätzlich zieht die erste Iteration der Schleife einen Datenfehlschlag auf sich, was bei diesem Beispiel 40 Zyklen erfordert. Demgemäß vermeidet Vorausabrufen die meisten Cachespeicherfehlschläge, so daß die Ausführungszeit auf 1140 Zyklen reduziert ist, d.h. 1000 Zyklen, um die ursprünglichen Schleifenbefehle auszuführen + 100 Zyklen für die Vorausabrufbefehle + 40 Zyklen für den anfängliche Cachespeicherfehlschlag, bevor der erste Vorausabrufbefehl ausgeführt wird. Danach überlappen die Vorausabrufbefehle die 40-Zyklen-Datencachespeicherfehlschlagwartungszeit mit der Ausführung von vier (11-Zyklen) Schleifeniterationen.
  • Ungünstigerweise wird bei jedem Durchgang durch die Schleife ein neuer Vorausabrufbefehl ausgeführt. Wo die Übertragungseinheit zwischen dem Hauptspeicher und dem Cachespeicher eine Cachespeicherzeile ist, sind einige der Vorausabrufungen redundant, da sich eine Vorausabrufung für eine bestimmte Arrayposition auf die gleiche Cachespeicherzeile beziehen kann wie die Vorausabrufung für nachfolgende Arraypositionen. Diese Redundanz tritt auf, weil es benachbarte Arraypositionen in der gleichen Cachespeicherzeile gibt, und das System gibt einen redundanten Befehl an das Speichersystem aus, um die gleiche Cachespeicherzeile mehrfach wiederzugewinnen. Typischerweise befolgen Computersysteme, die diesen Typ von Vorausabrufbefehl unterstützen, die Befehle, um zu bestimmen, ob eine angeforderte Adresse zum Vorausabrufen einer Cachespeicherzeile mit einer späteren Vorausabrufung auf der gleichen Cachespeicherzeile übereinstimmt. In einem solchen Fall wird die zweite Vorausabrufanforderung an den Hauptspeicher fallen gelassen.
  • Obwohl redundante Vorausabrufungen typischerweise fallengelassen werden, ist es trotzdem wichtig, daß Vorausabrufbefehle, die sich auf die gleiche Cachespeicherzeile beziehen, nicht mehrfach ausgeführt werden, da der Vorausabrufbefehl selber einiges an Berechnungszeit benötigt. Der Prozessor muß den Vorausabrufbefehl abrufen und ausführen, verstehen, auf welche Datenadresse sich der Befehl bezieht, und dann auf den Datencachespeicher zugreifen um zu überprüfen, ob sich die Daten bereits in dem Cachespeicher befinden.
  • Es ist zu beachten, daß der Kompilierer verantwortlich ist für das Einfügen von Vorausabrufbefehlen in einen Schleifenkern, welche die Speicheradresse von Datenelementen spezifizieren, auf die in Zukunft zugegriffen wird. Die Speicheradresse wird bestimmt auf der Basis der Anzahl von Schleifeniterationen im voraus (d.h. des Vorausabrufiterationsabstands oder PFID), um die Datenelemente vorausabgerufen werden müssen, um die Zeit vollständig zu verstecken, die erforderlich ist, um potentielle Datencachespeicherfehlschläge zu bedienen. Der PFID wird unter Berücksichtigung der Natur der Schleifenkernanweisungen und Charakteristika des Zielprozessors und des Speichersystems bestimmt. Für eine "kurze" Schleife, d.h. eine, die nur zwei Zyklen pro Iteration zum Ausführen verwendet, müßte der PFID beispielsweise 50 sein, um eine 100-Zyklen- Datencachespeicherfehlschlaglatenzzeit unterzubringen.
  • Der Schlüssel zu effizientem Datenvorausabrufen ist es dann, die Ausführung der Befehle des Computers in einem Stück Code, wie z.B. einer Schleife, mit der Zeit zu überlappen, die benötigt wird, um die Daten von dem Speicher zurückzugewinnen und in dem Prozessorcachespeicher zu plazieren, und dies auf eine Weise zu tun, die redundante Vorausabrufungen vermeidet.
  • Idealerweise wird der Cachespeicherfehlschlag-Mehraufwand durch wohlüberlegtes Einfügen von Vorausabrufbefehlen vollständig beseitigt. Unter erneuter Referenz auf das obige Beispiel, bei dem die Schleife 100 Iterationen ausführt, wobei jede Iteration jeweils 11 Zyklen benötigt (10 Zyklen für den ursprünglichen Schleifenkernbefehl + 1 Zyklus für den Vorausabrufbefehl + 40 Zyklen für einen anfänglichen Cachespeicherfehlschlag bevor das Vorausabrufen beginnt), und die Zeit, die benötigt wird, um die Schleife zu durchlaufen, nur 1140 Zyklen beträgt, was viel besser ist als die 2000 Zyklen des obigen Beispiels in Fig. 4.
  • 1140 Zyklen ist jedoch immer noch nicht ganz so gut wie 1000 Zyklen. Ein Weg, um die Einsparungen bei der Prozessorausführzeit weiter zu erhöhen, ist die Verwendung einer wohlbekannten Technik, die als Schleifenentrollen bzw. Schleifenausbreiten bezeichnet wird. Beim Schleifenentrollen wird der Kern der Schleife vervielfältigt. Dies reduziert die Anzahl der Male, die die Schleife ausgeführt wird, um einen Faktor, der gleich ist wie die Anzahl der Vervielfältigungen, obwohl jedesmal, wenn der Code ausgeführt wird, mehr Befehle auszuführen sind. Folglich wird beim Schleifenentrollen genau der gleiche Arbeitsumfang ausgeführt, aber die Schleife ist jetzt umorganisiert.
  • Es ist jedoch zu beachten, daß, da der Schleifenabschlußzweig nicht so oft vervielfältigt werden muß wie der Schleifenkern entrollt wird, (in der Tat braucht eine entrollte Schleife typischerweise nur einen Schleifenabschlußzweig) das Schleifenentrollen selbst zu verbesserter Leistungsfähigkeit führen kann.
  • Beispielsweise zeigt Fig. 6 die Schleife von Fig. 3, nachdem die Schleife viermal entrollt wurde. Folglich wird die Schleife statt 100 mal 25 mal ausgeführt. Man nehme an, daß ein Schleifenabschlußzweig einen Zyklus zum Ausführen benötigt. Jede Iteration in der entrollten Schleife würde dann 37 Zyklen erfordern (4 · 9 Zyklen + 1 Zyklus) und die Gesamtschleifenausführungszeit ist gleich wie (25 Iterationen · 37 Zyklen) + (25 Iterationen · 40 Zyklen/Cachespeicher- Fehlschläge) = 1925 Zyklen.
  • Im Zusammenhang der Erfindung und dem oben beschriebenen Beispiel, , ist es notwendig, Daten zwei Iterationen im Voraus vorausabzurufen (da eine Iteration im voraus nicht ausreicht, um eine 40-Zyklen-Cachespeicherfehlschlaglatenzzeit unterzubringen), falls jede Iteration der entrollten Schleife 37 Zyklen erfordert, wobei die Schleife 4 mal entrollt wird. Falls der Vorausabrufbefehl an das Ende der Schleife gesetzt wird, wird die Schleife ausgeführt, bevor ein Vorausabrufbefehl durchgeführt wird. Dies schafft nicht die optimale Operation der Schleife. Folglich ist die Plazierung des Vorausabrufbefehls wesentlich. Es ist daher notwendig, den Vorausabrufbefehl an einem Punkt zu plazieren, der ausreichend Zeit liefert für einen Vorausabrufbefehl, bevor die Schleife die Ausführung beendet. Falls der Vorausabrufbefehl beispielsweise oben an der Schleife plaziert wird, führt die Schleife den gleichen Arbeitsumfang durch, aber überlappt die Zeit zum Warten eines möglichen Datencachespeicherfehlschlags wirksamer für nachfolgende Iterationen mit der Berechnung, die in der aktuellen Iteration durchgeführt wird.
  • Für das obige Beispiel, bei dem es 100 Iterationen einer 10-Zyklen-Schleife gibt, die insgesamt 1000 Zyklen benötigt, kosten die Vorausabrufbefehle 100 Zyklen + einen 40- Zyklus-Cachespeicherfehlschlag für die erste Iteration. Folglich ist die Ausführung der Schleife von 2000 Zyklen auf 1140 Zyklen reduziert. Durch Hinzufügen von Schleifenentrollen in diesem Beispiel, bei dem die Schleife durch einen Faktor von 4 (siehe Fig. 6 und 7) entrollt wird, kann jede Iteration der Schleife 38 Zyklen benötigen (37 Zyklen + 1 Zyklus für den Vorausabrufbefehl). Folglich ist die Ausführungszeit für die Schleife gleich 38 Zyklen · 25 Iterationen + 80 Zyklen für zwei Cachespeicherfehlschläge bevor das Vorausabrufen beginnt = 1030 Zyklen. Folglich ist deutlich, daß die hierin offenbarten Techniken eine wesentliche Verbesserung bei der Ausführungszeit für eine Schleife erzeugen.
  • Es ist anzumetken, daß in einigen Fällen der Vorausabrufbefehl keine zusätzlichen Zyklen zum Ausführen kostet. Dies liegt daran, daß viele moderne Prozessoren superskalar sind, d.h. sie können mehrere Befehle in einem Zyklus ausführen, z.B. einen Ladevorgang mit einem Addiervorgang. Vorausabrufbefehle sind ähnlich wie ein Ladevorgang, da sie sich auf den Speicher beziehen. Falls folglich mehrere Addiervorgänge in einer Schleife vorkommen, erhöht Hinzufügen eines zusätzlichen Vorausabrufbefehls nicht die Zeit, die notwendig ist, um jede Iteration der Schleife auszuführen, weil der Vorausabrufbefehl parallel mit dem Addierbefehl ausgeführt wird.
  • Ein wichtiges Merkmal der Erfindung identifiziert Schleifen und Zugriffstrukturen, um eine Bestimmung zu ermöglichen, wie viele Zyklen den Schleifeniterationen gewidmet sind, und erlaubt dadurch Einfügung des Vorausabrufbefehls an eine Position eines Arrays, die ausreichend weit im voraus ist, um sicher zu stellen, daß die Fehlschlagzeit minimiert ist. Ein Problem liegt darin, daß Schleifen auf viele verschiedene Weisen codiert sein können. Es ist daher notwendig, unterschiedliche Typen von Schleifen zu erkennen. Beispielsweise gibt es einige Schleifen, die nicht immer durch Vorausabrufen gehandhabt werden.
  • In der Erfindung übersetzt der Kompilierer die Anwendung auf hoher Ebene in einem Befehlsstrom, den der Prozessor ausführt, wobei der Kompilierer an günstigen Punkten Vorausabrufbefehle in den Befehlsstrom eingibt, die eine Datenrückgewinnung von dem Hauptspeicher in den Cachespeicher verursachen, bevor das Datenelement tatsächlich benötigt wird. Der Kompilierer sieht voraus, daß ein bestimmtes Datenelement zu einem bestimmten Zeitpunkt benötigt werden wird, und läßt den Prozessor nicht blind ausführen, bis er zu dem Zeitpunkt kommt, an dem der Prozessor blockiert ist und mehrere Dutzend Zyklen lang wartet, bis dieses Element von dem Hauptspeicher abgerufen ist.
  • Ein Vorteil, den Prozessor die anderen Befehle weiter ausführen zu lassen, die vielleicht nichts mit dem Speicher zu tun haben, liegt darin, daß das System eine Überlappung erreichen kann. Während die Zugriffszeit zwischen Prozessor und Cachespeicher typischerweise 1 bis 5 Zyklen beträgt, liegt die Rückgewinnungszeit von Cachespeicher zu Speicher oft in der Größenordnung von 10 bis 100 Zyklen. Wenn der Prozessor tatsächlich zu dem Punkt kommt, an dem das Datenelement benötigt wird, ist es nicht notwendig, auf einen Cachespeicherfehlschlag zu warten, der 100 Prozessorzyklen benötigt. Folglich kann es, statt 100 Prozessorzyklen abzuwarten, nur notwendig sein, 20 Zyklen abzuwarten, weil 80 Zyklen Suchzeit versteckt und mit der vorherigen Ausführung überlappt sind.
  • Die Erfindung ist vorzugsweise in den Optimierer auf niedriger Ebene des Kompilierers implementiert, um Vorausabrufbefehle an günstigen Punkten in den Code einzufügen. Insbesondere fügt die Erfindung Vorausabrufbefehle in Schleifen ein. Ein Vorteil des Einfügens von Vorausabrufbefehlen in Schleifen liegt darin, daß die Datenreferenzstruktur einer Schleife dazu tendiert, regelmäßig zu sein, und der Kompilierer ist besser in der Lage, die Art von Speicherelementen vorherzusagen, die vermutlich in der Zukunft erforderlich sind, wobei die Zukunft nicht die aktuelle Iteration der Schleife ist, sondern fünf oder sechs Iterationen in der Zukunft. Wie oben ausgeführt hängt dies von den Charakteristika der Befehle, die innerhalb der Schleife gefunden werden, ab. Es ist daher notwendig, den Zeitpunkt zu variieren, zu dem die Vorausabrufanforderung tatsächlich ausgegeben wird, auf der Basis der erwarteten Latenzzeit einer Schleifeniteration.
  • Der Kompilierer ist das Stück der Software, das Quellencode, wie z.B. C, BASIC oder FORTRAN, in ein binäres Bild übersetzt, das tatsächlich auf einer Maschine läuft. Typischerweise besteht der Kompilierer aus mehreren getrennten Phasen, wie es oben in Verbindung mit Fig. 2 erörtert wurde. Eine Phase wird als Front-End bezeichnet und ist verantwortlich für das Überprüfen der syntaktischen Korrektheit des Quellencodes. Falls der Kompilierer ein C- Kompilierer ist, ist es notwendig sicherzustellen, daß der Code ein legaler C-Code ist. Es gibt außerdem eine Codeerzeugungsphase, und die Schnittstelle zwischen dem Front-End und dem Codegenerator ist eine Zwischendarstellung auf hoher Ebene. Die Zwischendarstellung auf hoher Ebene ist eine verfeinerte Serie von Befehlen, die ausgeführt werden müssen. Beispielsweise kann eine Schleife auf der Quellenebene codiert sein als:
  • for(I = 0, I < 10, I = I + 1),
  • die in der Tat in eine Reihe von Schritten aufgespalten sein kann, wobei z.B. jedesmal durch die Schleife zuerst I hochgeladen wird und gegenüber 10 geprüft wird, um zu entscheiden, ob die nächste Iteration ausgeführt wird. Ein Codegenerator nimmt diese Zwischendarstellung auf hoher Ebene und wandelt sie in eine Zwischendarstellung auf niedriger Ebene um. Dies ist viel näher zu den tatsächlichen Befehlen, die der Computer versteht. Hinsichtlich des Verbesserns der Qualität der Zwischendarstellungen wird eine Zwischendarstellung auf niedriger Ebene, die durch einen Codegenerator erzeugt wird, typischerweise in einen Optimierer auf niedriger Ebene zugeführt.
  • Eine Optimiererkomponente eines Kompilierers muß die Programmsemantik beibehalten (d.h. die Bedeutung der Befehle, die von dem Quellencode in eine Zwischendarstellung auf hoher Ebene übersetzt werden, und darauffolgend in eine Zwischendarstellung auf niedriger Ebene und letztendlich eine ausführbare Datei), kann aber den Code in einer Weise umschreiben oder übertragen, die es dem Computer ermöglicht, einen "äquivalenten" Satz von Befehlen, der in weniger Zeit ausgeführt werden kann, auszuführen.
  • Moderne Kompilierer sind mit einem Optimierer auf hoher Ebene (HLO = high level optimizer) strukturiert, der typischerweise auf einer Zwischendarstellung auf hoher Ebene wirksam ist und eine wirksamere Zwischendarstellung auf hoher Ebene eines bestimmten Programms substituiert, das typischerweise kürzer ist. Beispielsweise kann ein HLO redundante Berechnungen eliminieren.
  • Bei dem Optimierer auf niedriger Ebene (LLO = low level optimizer) sind die grundsätzlichen Aufgaben im wesentlichen die gleichen wie bei dem HLO, außer daß der LLO auf einer Darstellung des Programms wirksam ist, die viel näher zu dem ist, was die Maschine tatsächlich versteht. Einzigartig führt die Erfindung Vorausabrufanalyse und Vorausabrufbefehlerzeugung im Zusammenhang mit einem Optimierer auf niedriger Ebene durch. Auf dieser Ebene gibt es keine semantischen Anmerkungen, sondern lediglich Befehle, wie z. B. Addieren, Laden und Speichern. Der Kompilierer identifiziert darin wiederholte Codesegmente, wie z.B. Schleifen, für die Vorausabrufbefehlerzeugung im Zusammenhang mit einem Optimierer auf niedriger Ebene.
  • Die Analyse, die der Kompilierer hierin verwendet, ist einfacher als die des Stands der Technik. Da die Erfindung außerdem im Zusammenhang mit einem Optimierer auf niedriger Ebene bei Rohbefehlen wirksam ist, ist es viel einfacher zu schätzen, wie viele Prozessorzyklen eine Schleifeniteration erfordert, und daher, wie viele Iterationen vor einem Datenvorausabrufbefehl in den Code eingefügt werden sollten.
  • Es gibt viele unterschiedliche Organisationen, die für einen Datencachespeicher möglich sind, aber eine mögliche Organisation, der nicht allzu ungewöhnlich ist, ist es, denselben hinsichtlich einer Reihe direkt abgebildeter Cachespeicherzeilen zu organisieren. Jede Cachespeicherzeile kann in der Lage sein, bis zu 32 Bytes Daten zu halten, so daß die Übertragungseinheit zwischen Hauptspeicher und dem Cachespeicher in Brocken von 32 Bytes ist. Der Prozessor kann eine Anfrage an das Speichersystem richten, und folglich sind die Daten in einer gut definierten Position in dem Cachespeicher plaziert, um es dem Prozessor zu ermöglichen, die Daten von dieser Position wiederzugewinnen. Falls der Cachespeicher in diesem Beispiel 32.000 Bytes groß ist, dann umfaßt er 1000 Zeilen, wobei jede Zeile 32 Bytes umfaßt. Jeder explizite Datenvorausabrufkompilierer muß letztendlich die Hardwarevorausabrufbefehle in die Codedarstellung auf niedriger Ebene einfügen. Ein Unterscheidungsmerkmal der vorliegenden Erfindung ist es, daß die Analyse, die erforderlich ist, um Ausführungsbefehle wirksam einzufügen, ebenfalls in dem Kontext eines Optimierers auf niederiger Ebene durchgeführt wird. Darüber hinaus wird die Einfügung der Vorausabrufbefehle auf eine Weise durchgeführt, die synergetisch ist mit anderen Optimierungen auf niedriger Ebene, wie z.B. Schleifenentrollen, Registerneuzuordnung und Befehlsplanung.
  • Die Erfindung befindet sich hierin innerhalb der Domain des Optimierers auf niedriger Ebene 24. Fig. 8 ist ein Blockdiagramm, das einen Optimierer auf niedriger Ebene für einen Kompilierer zeigt, der einen Vorausabruftreiber 34 gemäß der Erfindung umfaßt.
  • Der Optimierer auf niedriger Ebene 24 gemäß dem bevorzugten Ausführungsbeispiel der Erfindung kann jede Kombination bekannter Optimierungstechniken umfassen, wie z.B. diejenigen, die eine lokale Optimierung 35, eine globale Optimierung 36, eine Schleifenidentifizierung 37, eine schleifeninvariante Codebewegung 38, ein Schleifenentrollen 30, eine Registerneuzuordnung 31 und eine Befehlsplanung 32 vorsehen. Die Erfindung schafft einen Vorausabruftreiber 34, der zusammen mit solchen bekannten Techniken wirksam ist.
  • Die nachfolgenden Abhandlungen beziehen sich auf die unterschiedlichen Elemente des in Fig. 8 gezeigten Optimierers auf niedriger Ebene.
  • - Lokale Optimierungen umfassen Codeverbesserungstransformationen, die auf einer Basisblock-um-Basisblock- Basis angewendet werden. Für die Zwecke dieser Erörterung entspricht ein Basisblock der längsten zusammenhängenden Sequenz von Maschinenbefehlen ohne jegliche eingehenden oder ausgehenden Steuerungsübertragungen, ausgenommen Funktionsaufrufe. Beispiele lokaler Optimierungen umfassen eine lokale Elimination von allgemeinen Ausdrücken (CSE = common subexpression elimination), eine lokale Eliminierung von redundante Landungen und eine Guckloch-Optimierung.
  • - Globale Optimierungen umfassen Codeverbesserungstransformationen, die angewendet werden auf der Basis einer Analyse, die sich über Basisblockgrenzen spannt. Beispiele umfassen eine globale Eliminierung von allgemeinen Ausdrücken, eine Todcodeeliminierung und eine Registerförderung, die Ladevorgänge und, Speichervorgänge durch Registerreferenzen ersetzt.
  • - Eine Schleifenidentifizierung ist der Prozeß des Identifizierens von Codeabschnitten, die wiederholt ausgeführt werden (dies wird typischerweise durch eine Intervallanalyse durchgeführt).
  • - Eine Schleifeninvariante Codebewegung ist die Identifizierung von Befehlen, die mit einer Schleife positioniert sind, die auf jeder Schleifeniteration das gleiche Ergebnis berechnen und das Neupositionieren solcher Befehle außerhalb des Schleifenkerns.
  • - Eine Registerzuweisung und Befehlplanung ist der Prozeß des Zuweisens von Hardwareregistern zu symbolischen Befehlsoperanden und das Neuordnen von Befehlen, um Laufzeitpipelineblockierungen zu minimieren.
  • Fig. 9 ist ein Blockdiagramm eines Vorausabruftreibers gemäß der Erfindung. In der Figur wird der Code innerhalb des Optimierers auf niedriger Ebene (numerischer Bezeichner 24 in Fig. 8) dem Vorausabruftreiber 34 zugeführt. Dies ist im Zusammenhang mit dem Optimierer auf niedriger Ebene von Fig. 8 durch Punkte A und B in der Figur gezeigt, wobei diese Punkte ebenfalls in Fig. 9 gezeigt sind, um auf den Vorausabruftreiber 34 sowohl in Fig. 8 als auch in Fig. 9 Bezug zu nehmen. Schleifenentrollen kann in die Erfindung eingebaut werden und ist in Fig. 9 als ein Modul gezeigt, das die Schleife eine ausgewählte Anzahl von Malen 92 entrollt. Schleifenkernanalyse 91 wird später in Verbindung mit Fig. 10 detaillierter erörtert.
  • Der Vorausabruftreiber schätzt den Vorausabrufabstand 93 und unterteilt dann die Speicherreferenzen, die in jeder Schleife auftreten, in nicht zusammenhängende Äquivalenzklassen 94 auf der Basis des symbolischen Adressausdrucks. Adressausdrücke sind innerhalb jeder Äquivalenzklasse 95 sortiert, und Vorausabrufbefehle, die für jede Äquivalenzklasse notwendig sind, werden berechnet 96. Schließlich werden die Vorausabrufbefehle erzeugt 97. Ein Codestrom, der durch den Vorausabruftreiber erzeugt wird, umfaßt sowohl die Zwischendarstellung auf niedriger Ebene als auch Vorausabrufbefehle, die in der Zwischendarstellung gemäß der vorliegenden Erfindung eingefügt wurden.
  • Die folgende detaillierte Beschreibung bezieht sich auf die unterschiedlichen Module, die in Fig. 9 gezeigt sind:
  • 1. Schleifenkernanalyse (siehe Fig. 10, bei der die Buchstaben G und H den gleichen Buchstaben in Fig. 9 entsprechen)
  • a. Identifizieren der Regionskonstanten 190. Diese sind Pseudoregister (symbolische Befehlsregisteroperanden), die nur verwendet werden und in dem Schleifenkern nicht definiert sind. Für die Zwecke der Vorausabrufanalyse sind nur Ganzzahlregionkonstanten von Bedeutung.
  • b. Identifizieren einfacher Basisschleifeninduktionsvariablen 191. Eine einfache Basisinduktionsvariable (BIV = basic induction variable) ist ein Pseudoregister, dessen Schleifenkerndefinitionen alle in der folgenden Form ausgedrückt werden können:
  • BIV = BIV + biv_delta
  • wobei "biv_delta" jeder arithmetische Ausdruck ist, der nur reine oder Regionskonstanten umfaßt. Bei dem unteren Beispiel ist die Variable "k" eine Regionskonstante und die Variable "i" ist eine BIV mit einer einzelnen Schleifenkerndefinition, deren "biv_delta"-Begriff (2*k) entspricht.
  • Die Nettoschleifeninkrementierung für eine BIV ist der Gesamtbetrag, um den die BIV auf jeder Schleifeniteration inkrementiert wird.
  • Es heißt daß eine BIV eine gut definierte Schleifeninkrementierung aufweist, wenn der Gesamtbetrag, um den die BIV inkrementiert wird auf jeder Schleifeniteration gleich ist. Die BIV-Schleifeninkrementierung in diesem Fall ist einfach die Summe der "biv_delta"-Werte, die jedem dieser Schleifenkerndefinitionen zugeordnet sind.
  • Es ist darauf hinzuweisen, daß eine BIV mit bedingten Schleifenkerndefinitionen keine gut definierte Schleifeninkrementierung aufweist.
  • c. Berechnen und Linearisieren von Adressausdrücken für Speicherreferenzen 192. Dies umfaßt zunächst das Identifizieren des Adressausdrucks, der den Speicherreferenzen zugeordnet ist. Dies wird typischerweise durchgeführt durch rekursives Zurückverfolgen der Erreichungsdefinitionen für die Registeroperanden von basisverwandten und indexierten Lade- und Speichervorgängen, die in dem Schleifenkern auftreten, und Konstruieren eines Binäradressausdruckbaums, bei dem die inneren Baumknoten einfache arithmetische Operationen (+, -, *) repräsentieren, und die Blattknoten entweder eine reine Konstante, eine Regionskonstante oder ein BIV repräsentieren. Die Zurückverfolgung endet ohne Erfolg, wenn eine Nicht-BIV-Registeroperande mehrere Erreichungsdefinitionen aufweist oder wenn der Adressausdruck aus einem anderen Grund nicht als ein einfacher binärer Ausdruckbaum ausgedrückt werden können. Speicherreferenzen, deren Speicheradresse nicht als solch ein binärer Ausdruckbaum ausgedrückt werden kann, werden für Vorausabrufzwecke nicht weiter berücksichtigt.
  • Der Adressausdruckbaum wird dann linearisiert, falls möglich hinsichtlich einer einzigartigen BIV, was bedeutet daß er in die folgende Form umgeschrieben wird:
  • a_exp * BIV + b_exp
  • wobei "a_exp" und "b_exp" selbst arithmetische Ausdrücke sind, die nur Summenausdrücke umfassen, von denen jeder ein Produkt ist, das entweder literale oder Regionganzzahlkonstanten umfaßt. Der Begriff "BIV" bezieht sich auf den Wert der Basisinduktionsvariable am Beginn des Schleifeneingangsbasisblocks (der Basisblock, der das Ziel des Ast ist, der die Hinterkante der Schleife repräsentiert).
  • Ein Adreßausdruck, der auf diese Weise linearisiert werden kann, wird als "affin" angesehen. Der "a_exp" -Begriff eines affinen Adressausdrucks multipliziert mit der Nettoschleifeninkrementierung der BIV wird auch als Speicherschritt bezeichnet. Außerdem ist jeder solchen Speicherreferenz eine Speicherdatengröße zugeordnet, die von dem Speicherreferenzoperationscode abgeleitet werden kann, d. h. von einer Vollwortladeoperation würde angenommen, daß sie eine Datengröße von 4 Byte aufweist.
  • Speicherreferenzen mit affinen Adreßausdrücken, die eine BIV mit einer gut definierten Nettoschleifeninkrementierung umfassen, die eine Kompilierzeitkonstante ist, und deren "a_exp"-Begriff nicht Null ist, sind die einzigen Speicherreferenzen, die für Datenvorausabrufzwecke weiter analysiert werden.
  • In dem Beispiel unten, das indexierte Referenzen auf 4- Byte-Ganzzahlarrays A, B, C und D enthält,
  • ist die Variable "I" eine BIV und die Adressausdrücke, die mit den Referenzen auf A, B, und D verbunden sind, würden als affin angesehen, da ihre Speicheradressen jeweils ausgedrückt werden können als:
  • (4) * i + (16 + &A[0])
  • (8) * i + )32 - 8*k + &B[0])
  • (4) * i + (&D[0])
  • wobei sich die Schreibweise "&X[0]" auf die Regionskonstantvariable bezieht, die die Adresse des nullten Elements von Array X repräsentiert.
  • Es ist jedoch anzumerken, daß der Adressausdruck, der der Referenz auf Array C zugeordnet ist, nicht als affin angesehen wird.
  • 2. Entrollen der Schleife falls möglich:
  • a. Berechnen des maximalen Vorausabrufentrollfaktors U. Das Ziel hierbei ist es, den größten Entrollfaktor U zu bestimmen, der verwendet werden kann, um den Vorausladebefehlmehraufwand zu minimieren, ohne Speicherschritte zu bewirken, die weniger oder gleich der Datencachespeicherzeilengröße sind, um die Datencachespeicherzeilengröße zu übertreffen.
  • Der maximale Vorausberechnungskontrollfaktor U wird wie folgt berechnet:
  • U = Schleifenentrollfaktor berechnet mit anderen Kriterien (z.B. Schleifenkerngröße, erwartete Auslöserzahl, Auslöserzahlteilbarkeit usw.).
  • Für jede affine Adreßausdruckreferenz, die im Zusammenhang einer BIV mit einer gut definierten konstanten Nettoschleifeninkrementierung "net_Schleife_delta" zugeordnet ist, führe man aus:
  • b. Falls U > 1, Schleifenkern U mal Entrollen und Loopanalyse (Schritte a-c) auf entrolltem Schleifenkern wiederholen.
  • 3. Schätzen des minimal erforderten Vorausabrufiterationsabstands (PFID):
  • Der Vorausabrufiterationsabstand ist die Anzahl der Voraus- Schleifeniterationen, um die Daten vorausabgerufen werden sollten, damit die Daten in dem Cachespeicher zugänglich sind, wenn sie von dem Prozessor benötigt werden, unter der Annahme, daß die Daten nicht von Anfang an in dem Cachespeicher waren. Der PFID wird wie folgt auf der Basis der erwarteten Cachespeicherfehlschlaglatenzzeit und der minimalen Quellenbeschränkten Latenzzeit für jede Schleifeniteration berechnet:
  • PFID = Aufrundungszahl (durchschnittl_Fehlschlag_ Latenzzeit/durchschnittl_Schleifen_Iteration_Latenzzeit)
  • Es gibt zwei konkurrierende Beschränkungen hinsichtlich der PFID-Auswahl:
  • Zunächst sollte der PFID ausreichend groß sein, um die erwartete durchschnittliche Cachespeicherfehlschlaglatenzzeit zu verstecken.
  • Zweitens sollte der PFID nicht so groß sein, daß die vorausabgerufenen Daten von dem Cachespeicher durch eine eingreifenden kollidierende Speicherreferenz verschoben werden, bevor wirklich darauf Bezug genommen wird.
  • Es ist schwierig, die optimale durchschnittliche erwartete Speicherlatenzzeit zu bestimmen. Während die beste Umlaufspeicherzugrifflatenzzeit in einem System beispielsweise 50 Zyklen sein kann, ist es wahrscheinlich, daß dieselbe in einem anderen System, das einen langsameren Bus verwendet, unterschiedlich ist. Ferner tendieren Buskonflikte und Speicherbankkonflikte dazu, die Speicherzugrifflatenzzeit zu erhöhen.
  • Trotzdem wird die durchschnittliche Fehlschlaglatenzzeit heuristisch geschätzt als die minimale Anzahl von Prozessorzyklen, die zwischen dem Zeitpunkt, zu dem durch den Prozessor eine Anforderung an den Datencachespeicher gesendet wird und dem Zeitpunkt, zu dem die Daten zu dem Prozessor gesendet werden, verstreichen, unter der Annahme, daß die Daten nicht in dem Cachespeicher vorlagen.
  • Das Schätzen der durchschnittlichen Schleifeniterationslatenzzeit ist sogar noch schwerer durchzuführen, selbst für Einzelbasisblockschleifen. Bis das Planen und die Registerzuweisung durchgeführt sind, ist es nicht möglich, sicher zu wissen, wie viele Zyklen eine Schleifeniteration benötigen wird. Da es teuer und schwierig ist, die erreichbare Schleifeniterationslatenzzeit genau zu berechnen, wird statt dessen eine untere Grenze für die erreichbare Schleifeniterationslatenzzeit auf der Basis einer Maschinenressourcenverwendung berechnet. Dies ist für superskalare Prozessoren, die Befehle außerhalb der Reihenfolge ausführen und in der Lage sind, Operationslatenzzeiten bei der Laufzeit zu überlappen, ziemlich effektiv. Typischerweise beschränkt bei solchen Maschinen die Befehlsrückzugbandbreite die Ausführungszykluszahl am meisten. Folglich kann durch Fokussieren auf die Rückzugsbandbreitenanforderungen der Befehle, die in dem Schleifenkern vorliegen, eine untere Grenze für die erreichbare Schleifeniterationslatenzzeit berechnet werden.
  • Bestimmte Befehle, die wahrscheinlich schließlich gelöscht werden, sollten beim Berechnen der Schleifeniterationslatenzzeitschätzung ignoriert werden. Diese können Registerzu-Register-Bewegungsbefehle, Indexbefehle, die durch Neuzuweisung gelöscht werden können, umfassen, und Gleitkommamultiplizierungen und -addierungen, die in Gleitpunktmultiplizier- und -aufnummerierbefehle verschmolzen werden können.
  • Es sei angenommen, daß ein Außer-der Reihe-Zielprozessor, zwei Speicherbefehle und zwei ALU- oder Gleitkommaoperationen pro Zyklus zurückziehen kann, und es sei angenommen, daß der Schleifenkern besteht aus:
  • 5 Speicheroperationen,
  • 6 ALU-Operationen und
  • 7 Gleitkommaoperationen
  • wobei drei der ALU-Operationen bei der Adressierung von Ausdrücken teilnehmen, die wahrscheinlich durch eine Registerneuzuordnung eliminiert werden. Die untere Grenze bei der Schleifeniterationslatenzzeit würde dann S Zyklen betragen, berechnet als der größere Wert von 5/2 und ((6 - 3) +7)/2.
  • Es ist nun außerdem notwendig, das Thema der Schleifen anzusprechen, die interne Zweige aufweisen. Die minimale Schleifeniterationslatenzzeit für solche Schleifen wird geschätzt unter Verwendung vorher gesammelter Ausführungsprofilinformationen, welche die Ausführungszahl für jeden Basisblock in dem Schleifenkern anzeigen. Die minimale Zykluszahl für jeden Basisblock wird berechnet auf der Basis der Ausführungsbeschränkungen für die Befehlsmischung innerhalb des Basisblocks.
  • Die minimale Zykluszahl wird über jeden Basisblock summiert, der mehr als ein halb mal so oft ausgeführt wird wie der Schleifeneingangsknoten, um eine Schätzung für die minimale Schleifeniterationslatenzzeit zu erzielen.
  • 4. Identifizieren von Äquivalenzklassen:
  • Um die Art der expliziten Vorausabrufbefehle zu entscheiden, die in den Schleifenkern eingeführt werden, werden zunächst einheitlich erzeugte Äquivalenzklassen von Speicherreferenzen identifiziert. Dies sind im wesentlichen nicht zusammenhängende Sätze von Speicherreferenzen, von denen bekannt ist, daß sich ihre Adressausdrücke um eine Kompilierzeitkonstante unterscheiden. Dies wird durchgeführt, um dazu beizutragen, die Gruppen-Raum und Gruppen-Zeit- Lokalität unter den unterschiedlichen Speicherreferenzen klar zu erfassen, was wiederum dazu beitragen kann, den Vorausabrufbefehlmehraufwand zu reduzieren.
  • Es sei jeder affine Adreßausdruck, der einer BIV zugeordnet ist, mit einer Kompilierzeit-konstanten Nettoschleifeninkrementierung in einer bestimmten Gruppe plaziert, so daß alle Adressausdrücke innerhalb einer Gruppe die folgenden Eigenschaften teilen:
  • - sie sind alle der gleichen BIV zugeordnet
  • - sie weisen alle den gleichen "a_exp" -Begriff auf
  • - ihre "b_exp"-Begriffe unterscheiden sich um eine Kompilierzeitkonstante
  • Der folgende Algorithmus wird verwendet, um dies zu erreichen:
  • - den Satz der einheitlich erzeugten Äquivalenzklassen, UGEC = {} sein lassen
  • - jeden affinen Adressausdruck E(biv, a_exp, b_exp) zu einer Arbeitsliste W addieren.
  • Wiederholen von
  • } bis die Arbeitsliste W leer ist
  • Bedenken jeder Äquivalenzklasse Q abwechselnd und Durchführen folgender Schritte:
  • 5. Sortieren der Adressausdrücke innerhalb jeder Äquivalenzklasse auf der Basis ihrer b_exp'-Begriffe und ersetzen der Mehrfachadressausdrücke mit identischen b_exp'- Begriffen mit einem einzigen repräsentativen Adressausdruck.
  • Da sich durch die Organisation die Adressausdrücke, die zu der gleichen Äquivalenzklasse gehören, durch eine einfache Konstante in ihren b_exp'-Begriffen unterscheiden, sollte es immer möglich sein, sie auf der Basis zunehmender b_exp'-Werte zu sortieren.
  • "E_low" den Adressausdruck in Q mit dem niedrigsten b_exp'- Wert sein lassen. Berechnen eines relativen Äquivalenzklassenoffsets "eq_offset" für jeden Adressausdruck E in Q, als:
  • E.eq_offset = E.b_exp' - E_low.b_exp'
  • 6. Berechnen von Vorausabrufbefehlen, die benötigt werden, um vollständige Cachespeicherfehlschlagabdeckung für die Äquivalenzklasse Q sicherzustellen.
  • Das Ziel hierbei ist es, die geringste Anzahl von Vorausabrufbefehlen in den Schleifenkern einzufügen, um sicherzustellen, daß in dem Dauerbetriebszustand wird für jede bestimmte Cachespeicherzeile ein Vorausabrufbefehl ausgegeben, die durch die Adressausdrücke in der Äquivalenzklasse Q referenziert werden. Unnötige Vorausabrufbefehle werden falls möglich vermieden, durch Ausnutzen jeglicher Gruppen- Raum- oder Gruppen-Zeit-Lokalität, die unter den Speicherreferenzen innerhalb jeder Äquivalenzklasse auftreten.
  • Das Verfahren des Bestimmen des geringsten Anzahl von Vorausabrufbefehlen, die benötigt werden, um vollständige Cachespeicherfehlschlagabdeckung sicher zu stellen, hängt von der Größe des Speicherschritts M' ab, der mit der Äquivalenzklasse verbunden ist.
  • Falls M' < = Cachespeicherzeilengröße ist, dann wird eine Vorausabrufstrategie, die für kleine Schritte geeignet ist, verwendet, andernfalls wird eine Vorausabrufstrategie, die für große Schritte geeignet ist, verwendet. Es ist anzumerken, daß bei großen Schritten die Cachespeicherzeilenausrichtung von Datenelementen in Betracht gezogen werden muß.
  • In jedem Fall ist es zunächst notwendig, Cluster von Referenzen innerhalb der einheitlich erzeugten Äquivalenzklasse zu identifizieren. Ein Cluster besteht aus einem oder mehreren Speicherreferenzen, die aufeinanderfolgend in der Äquivalenzklassenliste auftreten, die nach "eq_offset" sortiert ist, mit einem gut definierten Clusterführer. Der Clusterführer wird verwendet, um Vorausabrufdaten für alle Bauglieder des Clusters zu erzeugen. Das Ziel hierbei ist es, die Referenzen innerhalb einer Äquivalenzklasse zu eliminieren, die andere Referenzen innerhalb der Äquivalenzklasse hinter sich herziehen. Die Referenzen, die stehen bleiben, sind im wesentlichen Clusterführer.
  • Die Art und Weise, auf die die Speicherreferenzen in Cluster gruppiert werden, hängt von der relativen Größe des Speicherschritts im Vergleich zu der Cachespeicherzeilengröße ab.
  • a. Clusteridentifikation für Kleinschritt- Äquivalenzklassen
  • Es ist notwendig, die Adressausdrücke in der Äquivalenzklasse in der Reihenfolge zunehmender "eq_offset"-Werte zu bedenken, und zu bestimmen, ob jeder Adressausdruck den direkt nachfolgenden Adressausdruck in der Äquivalenzklasse hinter sich herzieht, und falls dies der Fall ist, dieses aus der Äquivalenzklasse fallen lassen.
  • B(i) und B(i + 1) benachbarte Speicherreferenzen innerhalb der sortierten Äquivalenzklassenliste sein lassen. Wenn der Speicherschritt < = Cachespeicherzeilengröße ist, wird B(i) angesehen als in dem gleichen Cluster wie B(i + 1), und daher für Vorausabrufbedenken ausgelassen, falls
  • wobei der Vorausabrufspeicherabstand berechnet wird als das Produkt von PFID und des wirksamen Speicherschritts M' für die Äquivalenzklasse.
  • Die Logik dahinter ist, daß, falls B(i + 1) eine Referenz B(i) um weniger als die Vorausabrufspeicherabstand führt, dann gibt es keinen wirklichen Sinn zum Einfügen eines Vorausabrufbefehls wegen B(i). Obwohl einige der anfänglichen PFID-Ausführungen von B(i) innerhalb der Schleife Cachespeicherfehlschläge erleiden können, würden nachfolgende Ausführungen von B(i) entweder ihre Daten in dem Cachespeicher finden oder müssen sehr viel kürzer warten als eine vollständige Cachespeicherfehlschlaglatenzzeit um ihre Daten von dem Hauptspeicher zurückzugewinnen, da B(i + 1) oder ein Vorausabrufbefehl, der B(i + 1) zugeordnet ist, die Speicherrückgewinnung zu einem früheren Zeitpunkt ausgelöst hätte. [Dies selbstverständlich unter der Annahme, daß Konflikt/Kapazitätfehlschläge die Daten zu dem Zeitpunkt, zu dem B(i) B(i + 1)] einholt, nicht von dem Cachespeicher verschoben haben
  • Die letzten PFID-Schleifeniterationen können abgelöst werden, wie es bei Mowry et al. beschrieben ist, um den Mehraufwand redundanter Vorausabrufbefehle zu vermeiden, die ausgeführt werden würden für Datenelemente, auf die durch die ursprüngliche Schleife nicht zugegriffen wird.
  • Wie in Fig. 9 gezeigt, ist das Modul, das die Vorausabrufbefehle berechnet, die notwendig sind, um die Äquivalenzklasse zu bestimmen 96, durch die Buchstaben C und D identifiziert, diese Buchstaben werden verwendet, um eine detailliertere Erklärung des Moduls, die in Fig. 11 gezeigt ist, anzuzeigen. In der Figur ist der Vorausabruftreiber so gezeigt, daß er ein Modul umfaßt, das die Vorausabrufbefehle die benötigt werden, berechnet, 96, wobei Kleinschritt- Vorausabrufkandidaten 201 und Großschritt- Vorausabrufkandidaten 202 gemäß einem Erfassungsmodul 200 identifiziert werden. Der Algorithmus für Clusteridentifikation mit kleinen Schritten wird unten gegeben:
  • Für jeden Adressausdruck "p" in der aktuellen Äquivalenzklasse in geordneter Weise, außer dem allerletzten Adressausdruck
  • - Markieren des allerletzten Adressausdrucks P in der Äquivalenzklassenliste als einen Clusterführer
  • - p.trailing_offset = p.leading_offset = p.eq_offset sein lassen
  • Die Adressausdrücke, die nach diesem Aussonderungsprozeß in der Äquivalenzklasse verbleiben, sind alle Clusterführer.
  • b. Clusteridentifikation für Großschritt- Äquivalenzklassen.
  • Der Algorithmus zum Erfassen der geringsten Anzahl von Vorausabrufkandidaten, die für eine Äquivalenzklasse mit einem großen Schritt benötigt werden, ist leider etwas komplizierter als derjenige, der für Kleinschritt- Äquivalenzklassen verwendet wird. Der Hauptgrund dafür liegt darin, daß bei großen Speicherschritten die relative Cachespeicherzeilenausrichtung der Speicherreferenzen wichtig wird. Man bedenke beispielsweise die folgende "C" Schleifenverschachtelung:
  • Das obige Quellencodefragment schreitet durch das Array A in großen Inkrementen für jede Iteration der inneren j- Schleife. Es muß bestimmt werden, ob es ausreichend ist, nur einen Vorausabrufbefehl für A[j][i + 1] einzufügen, mit der Annahme, daß die A[j][i]-Referenz eine nachlaufende (trailing) Referenz ist. Die Antwort lautet Nein, da die zwei Referenzen eine Cachespeicherzeilengrenze überspannen könnten. Falls dies der Fall wäre, könnten die Referenzen auf A[j][i] den Cachespeicher verfehlen, möglicherweise bei jeder Iteration der j-Schleife, obwohl Daten für die A[j][i + 1]-Referenz vorausabgerufen werden.
  • Dadurch soll jedoch nicht gesagt werden, daß es keine Hoffnung zum gemeinsamen Verwenden von Vorausabrufbefehlen unter Referenzen innerhalb einer einheitlich erzeugten Äquivalenzklasse mit einem großen Schritt gibt. Falls beispielsweise die erste Referenz in der obigen j-Schleife für A [j - 1] [i + 1] gewesen wäre anstatt für A [j] [i], wäre eindeutig ein Vorausabrufbefehl ausreichend für beide Referenzen.
  • Um dieses System immun zu machen gegenüber den Launen relativer Cachespeicherzeilenausrichtung von Referenzen innerhalb einer Äquivalenzklasse, und doch gleichzeitig offensichtliche zeitliche Position zwischen den Referenzen auszunutzen, wird eine 2-Durchlauf-Strategie verwendet. Diese Strategie ist in Fig. 12 gezeigt. In dem ersten Durchlauf ist es notwendig, Cluster benachbarter Referenzen innerhalb der aktuellen Äquivalenzklasse zu identifizieren, die auf der Basis ihrer eq_offsets 205 sortiert sind. Das Unterscheidungsmerkmal eines jeden solchen Clusters ist, daß die Referenzen innerhalb des Clusters Gruppen-Raum-Lokalität teilen, aber nicht die Gruppen-Zeit-Lokalität.
  • Die führende Referenz innerhalb jedes solchen Clusters ist verantwortlich zum Vorausabrufen von Daten sowohl für sich selbst als auch jede andere Referenz in dem Cluster. Um schlechte Unterbrechungen mit Cachespeicherzeilenausrichtungen aufzunehmen, kann ein Clusterführer mehrere Vorausabrufbefehle verursachen, die jeweils eine Cachespeicherzeile von dem nächsten beabstandet sind, bis die gesamte Spanne des Clusters berücksichtigt ist. Um dies besser zu erklären, beachte man die folgende einfache Schleife, die möglicherweise das Ergebnis des Schleifenentrollschritts ist, wobei "A" eine Doppelpräzision-Arrayvariable ist, d. h. w/8-Byte Elemente:
  • i_Schleife:
  • A[i] = A[i + 1] = A[i + 2] = A[i + 3] = A[i + 4] = A[i + 5] = A[i + 6] = A[i + 7] =
  • i = i + 8
  • beende_i_Schleife;
  • Zunächst, da die Schleife BIV, "i" ein Nettoschleifeninkrement von 8 aufweist, und die Elementgröße von "A" 8 Bytes beträgt, ist dies eine Großschritt-Äquivalenzklasse eine 32-Byte Cachespeicherzeilengröße (8 · 8 Bytes = 64 Bytes) > 32 Bytes angenommen wird.
  • Alle 8 Referenzen auf "A" sind in dem gleichen Cluster plaziert, da sie Gruppen-Raum-Lokalität aufweisen und keine Gruppen-Zeit-Lokalität. Der Clusterführer ist die Referenz auf A[i +7] und die Spanne des Clusters ist 64 Bytes (d.h. &A[i + 7] - &A[i]). Falls der Vorausabrufspeicherabstand vorher auf 128 Bytes berechnet wurde, d.h. entsprechend einem Vorausabrufiterationsabstand von 2, ist es nur notwendig, drei Vorausabrufbefehle einzufügen, um die gesamte Spanne dieses 8-Bauglied-Clusters zu berücksichtigen. Diese drei Vorausabrufbefehle rufen im wesentlichen die folgenden Arrayelemente im Voraus ab:
  • Vorausabrufen A[i + 0 + 16]; p/f für Clusternachzügler
  • Vorausabrufen A[i + 3 + 16]; p/f für Clusternachzügler
  • Vorausabrufen A[i + 7 + 16]; p/f für einen
  • Clusterführer
  • Unabhängig von der Cachespeicherzeilenausrichtung des Clusterführers, stellen diese drei Vorausabrufbefehle sicher, daß alle der Clusterbauglieder Speichertransaktionen ausgelöst haben für Daten, welche sie zwei Iterationen im voraus verweist. Um die eigentliche Erzeugung dieser Typen von Vorausabrufbefehlen zu vereinfachen, werden Clusternachzügler sofort von der Äquivalenzklasse entfernt, und die Clusterspanne für den repräsentativen Clusterführer wird aufgezeichnet.
  • b.i. Der Algorithmus auf hoher Ebene für den ersten Durchlauf wird unten gezeigt:
  • - lasse q gleich letzten Adressausdruck in der aktuellen Äquivalenzklasse sein
  • - markiere q als einen Clusterführer
  • - lasse q.trailing_offset = q.leading_offset = q.eq_offset sein
  • für jeden Adressausdruck "p" in der aktuellen Äquivalenzklasse, betrachtet auf rückwärts sortierte Weise, Ignorieren von "q"
  • b.ii. Nachdem in dem ersten Durchlauf Clusterführer identifiziert wurden, versucht der Algorithmus die zeitliche Position zwischen Clustern (siehe das Modul, das durch den numerischen Bezeichnen 206 in Fig. 12 identifiziert ist) auszunutzen. Dieser Durchlauf ist etwas ähnlich zu dem Algorithmus, der verwendet wurde, um Vorausabrufkandidaten für Kleinschritt-Äquivalenzklassen zu identifizieren. Grundsätzlich, falls zwei benachbarte Cluster weniger als der Vorausabrufspeicherabstand voneinander entfernt sind, wie er zwischen dem Führer (leader) des nachlaufenden Clusters und dem Nachläufer (trailer) des führenden Clusters gemessen wurde, dann kann das nachlaufende Cluster von weiteren Vorausabrufbedenken entfernt werden.
  • Anstatt jedoch einfach das nachlaufende Cluster zu vergessen, ist es notwendig, das nachlaufende Cluster mit dem führenden Cluster zu verschmelzen. Der Algorithmus muß die Spanne des führenden repräsentativen Clusters erhöhen, weil die Spanne des verschmolzenen Clusters später verwendet wird, um zu bestimmen, wie viele Vorausabrufbefehle tatsächlich benötigt werden. Es ist anzumerken, daß die Größe eines verschmolzenen Clusters nicht den wirksamen Speicherschritt M' übersteigen darf, da andernfalls für die nachlaufende Referenz des verschmolzenen Clusters ein Vorausabrufbefehl unnötigerweise eingefügt wird. Statt dessen ist die Größe eines verschmolzenen Clusters festgelegt als nicht größer als der effektive Speicherschritt.
  • Eine weitere wichtige Überlegung beim Entscheiden zum Verschmelzen von Clustern ist, ob die Verschmelzung lohnend wäre. Im allgemeinen werden für ein Cluster C, dessen Spanne "C.s" Bytes ist, "C.p" Vorausabrufbefehle eingefügt. "C.p" kann berechnet werden als:
  • C.p = [ceiling (C.s/L)] + 1
  • wobei "L" die Cachespeicherzeilengröße ist. Falls eine Cluster C "C.b" Referenzen aufweist, gibt es keine Vorteile von der Position, die innerhalb des Clusters vorliegt, außer (C.p < = C.b). Dieses Rentabilitätskriterium wird indirekt sowohl bei dem Aufbau von Clustern im ersten Durchlauf als auch bei dem Verschmelzen von Clustern in dem zweiten Durchlauf angewendet. Das Rentabilitätskriterium, wie es in dem ersten Durchlauf angewendet wird, schlägt vor, daß keine zwei benachbarten Referenzen innerhalb eines Clusters größer sein sollten als eine Cachespeicherzeilengröße entfernt, da es sonst besser wäre, die Cluster in zwei Untercluster aufzubrechen. Ferner sollte die Spanne des Clusters, wie bei dem Abstand zwischen dem Kandidatclusternachläufer und dem aktuellen Clusterführer größer werden als der wirksame Speicherschritt M', wie oben erklärt. Die Größe eines verschmolzenen Clusters ist daher aus diesem Grund festgelegt auf nicht größer als der wirksame Schritt.
  • Bei dem zweiten Durchlauf, bei der Entscheidung, ob Cluster verschmolzen werden sollen, wird die Anzahl von Vorausabrufbefehlen, die für die verschmolzenen Cluster benötigt würden, unter Verwendung obiger Formel mit der Summe der Vorausabrufbefehle verglichen, die benötigt würden, falls die Cluster nicht verschmolzen werden.
  • Eine Raffinesse bei dem Clusterverschmelzungsdurchlauf liegt darin, daß es manchmal nicht lohnend erscheint, ein Cluster C(i) mit dem nächsten führenden Cluster C(i + 1) zu verschmelzen, selbst wenn es in einem größeren Zusammenhang lohnenswert gewesen wäre, C(i) mit C(i + 2) zu verschmelzen, unter der Annahme, daß C(i + 2) und C(i) weniger als der Vorausabrufspeicherabstand entfernt sind. Folglich werden nicht benachbarte Cluster für Verschmelzungszwecke untersucht, und der beste Cluster zum Schmelzen wird ausgewählt.
  • Falls entschieden wird, einen Cluster C(i) mit einem anderen Cluster C(j) zu verschmelzen, kann der relative Offset des verschmolzenen Clusterführers größer werden als der relative Offset der führenden Referenz von C(j). Folglich kann die Spanne eines verschmolzenen Clusters größer sein als einfach der Unterschied zwischen den ursprünglichen relativen Offsets von Clusterführer und Clusternachläufer. Der Algorithmus, der für den zweiten Durchlauf, d.h. den Clusterverschmelzungsdurchlauf verwendet wird, der dafür verwendet wird, um zeitliche Position zwischen Clustern auszunutzen, wird unten erklärt:
  • Der Algorithmus tastet die verbleibenden Adressausdrücke in der Äquivalenzklasse, von denen jeder ein Clusterführer ist, der in dem ersten Durchlauf identifiziert wurde, linear nach vorne ab und sucht nach Verschmelzungsmöglichkeiten mit den anderen führenden Clustern. In der Darstellung unten wird der Einfachheit halber angenommen, daß die einheitlich erzeugte Äquivalenzklasse einen positiven Schritt aufweist.
  • Ein notwendiger Zustand für einen nachlaufenden Cluster C(i) um zum Verschmelzen mit einer führenden Cluster C(j) zulässig zu sein, ist:
  • a) [C(j).trailing_offset - C(i).leading_offset] < pf memory_distance.
  • Anderenfalls würde C(j) den Cluster C(i) um mehr als gewünscht führen.
  • Nun lasse
  • m = ceiling[(C(j).trailing_offset - C(i).leading_offset)/M']
  • sein, wobei sich "trailing offset" und "leading offset" jeweils auf den eq_offset des Clusternachläufers und -führers beziehen. Es ist anzumerken, daß der nachlaufende CLuster das Ergebnis einer vorhergehenden Clusterverschmelzung sein kann, und so kann sein "trailing-offset" eventuell nicht einer Speicherreferenz entsprechen, die tatsächlich im Quellencode erscheint.
  • Es ist selbstverständlich erforderlich, daß 0 < m < PFID.
  • Es ist außerdem notwendig, die Spanne eines Clusters C(x) zu definieren als:
  • C(x).s = C(x).leading_offset - C(x).trailing_offset
  • Wie bereits vorher erwähnt, ist die Anzahl von Vorausabrufbefehlen die für einen bestimmten Cluster C(x) benötigt werden, gegeben durch C(x).p:
  • C(x).p = [ceiling(C(x).s/L)] + 1
  • wobei L die Cachespeicherzeilengröße ist.
  • Falls die Cluster C(i) verschmolzen wird mit dem Cluster C(j), dann ist die Spanne des verschmlozenen Clusters C(j') gegeben durch:
  • Damit die Verschmelzung des Clusters C(i) mit dem Cluster C(j) hinsichtlich des Reduzierens der Gesamtanzahl erforderlicher Vorausabrufbefehle lohnen ist, ist das Folgende notwendig:
  • C(j').P < = (C(i).P + C(j).p)
  • was bedeutet, daß
  • ceiling (c(j').s/L) < = (ceiling (C(i).s/L) + ceiling (C (J).s/L)).
  • Man lasse die Einsparungen, die durch das Verschmelzen der Cluster C(i) mit C(j) in einen kombinierten Cluster C(j') entstehen, definiert sein als:
  • Verschmelzung Einsparungen (i, j, j') = (C(i).p + C(j).p - (C(j').p.
  • Das Kriterium "b" zum Verschmelzen von Clustern kann nun artikuliert werden. Für ein Cluster C(i) unter den führenden Clustern C(j), die das Kriterium "a" erfüllen, wählt das System, den Cluster C(i) mit einem dieser Cluster C(j) zu verschmelzen, wobei:
  • Verschmelzung_Einsparungen (i, j, j') maximiert und nicht negativ ist.
  • Es ist anzumerken, daß, obwohl der Wert von "m", der wie oben erwähnt berechnet wurde, das minimale positive integrale Mehrfache des Schritts repräsentiert, das erforderlich ist, um eine Überlappung von C(i) mit C(j) zu erreichen, ist es außerdem notwendig zu prüfen, ob die Verwendung von (m - 1) eine kleinere Spanne erzielen könnte, und folglich weniger Vorausabrufbefehle für den verschmolzenen Cluster. Obwohl das Vorstehen des Clusters C(1) um (m - 1) Iterationen voraus sicherlich nicht bewirkt, daß es mit C(j) überlappt, kann der vorstehende C(i) Führer sehr nahe kommen zu dem C(j) Nachläufer, wodurch bewirkt wird, daß das System weniger Vorausabrufbefehle verwendet, als wenn C(i) um eine weitere Iteration vorsteht. Dies kann insbesondere zutreffen, falls der Schritt viel größer ist als die einzelnen Clusterspannen.
  • Folglich tastet der Algorithmus die verbleibenden Adressausdrücke, welche die in dem ersten Durchlauf identifizierten Cluster darstellen, in sortierter Reihenfolge ab und verschmilzt nachlaufende Cluster mit einem ausgewählten führenden Cluster durch Vorstehen des nachlaufenden Clusters um entweder m oder (m - 1) Iterationen voraus und durch Prüfen, ob beide Kriterien "a" und "b" zutreffen. Um einen nachlaufenden Cluster C(j) um m Iterationen nach vorne vorzustehen, um auszuwerten, ob er mit einem führenden Cluster C(j) verschmolzen werden sollte, berechnet des System die vorläufigen "leading_offset" und "trailing_offset"-Werte für den vorgeschlagenen verschmolzenen Cluster C(j') folgendermaßen:
  • lasse (C(j').leading_offset = C(i).leading_offset + (m * M') sein
  • lasse C(j').trailing_offset = C(i).trailing_offset + (m * M') sein
  • falls (M' > 0)
  • falls notwendig, passe C(j').trailing_offset an, um sicherzustellen, daß C(j').s M' nicht übertrifft, wie folgt:
  • C(j').s = ABS (C(j').leading_offset - C(j').trailing_offset)
  • falls (C(j').s > ABS(M'))
  • Wenn ein Cluster C(i) mit einem Cluster C(j)erfolgreich in ein Cluster C(j') verschmolzen wurde, wird C(i) von der Äquivalenzklassenliste entfernt.
  • 7. Erzeugen der Vorausabrufbefehle, die für jeden verbleibenden Clusterführer erforderlich sind.
  • Es ist notwendig, jeden Clusterführer abwechselnd zu bedenken, und wo "trailing_offset" für jeden Clusterführer anders ist als "leading_offset", so viele Vorausabrufbefehle wie nötig einfügen, um die gesamte Spanne des Clusters zu bedecken, d.h. von "leading_offset" nach unten bis zu "trailing_offset", wobei jede Vorausabrufbefehladresse L Bytes beabstandet ist.
  • Genauer gesagt, falls die Speicherreferenz, die einem Clusterführer entspricht, durch den folgenden Befehl dargestellt ist:
  • lade disp(Rb), Rt
  • wobei "disp" ein Verschiebungswert ist und Rb und Rt Pseudoregister sind, die dem Basisregister und Zielregister der Ladung entsprechen, dann werden einer oder mehrere Vorausabrufbefehle wie folgt in den Codestrom eingefügt:
  • vorausabrufen_inst new_disp (Rb)
  • wobei "new_disp" berechnet wird als disp + (M*PFID) + pf_disp, wobei "pf_disp" den konstanten Offset repräsentiert, der zu der Speicheradresse, die durch den Clusterführer referenziert wird, hinzugefügt werden muß, um die Basisadresse zu bilden, von der es notwendig ist, um den Vorausabrufspeicherabstand vorausabzurufen. Der Algorithmus, der verwendet wird, um die Vorausabrufbefehle auszugeben, wird nachfolgend gegeben:
  • -lasse L = Cachespeicherzeilengröße für jeden verbleibenden Cluster C(i) in der Äquivalenzklasse
  • Es ist anzumerken, daß bei dem Berechnen von new_disp der Originalspeicherschrittwert M, berechnet als (a_exp * net biv Schleife increment) verwendet wird, und nicht der konstant gefaltete Wert M'. Dies kann es erforderlich machen, einen Laufzeitregionkonstantausdruck in einem Register außerhalb des Schleifenkerns zu materialisieren, und Einfügen eines expliziten Addierbefehls innerhalb des Schleifenkerns, um die folgende Vorausabrufbefehladresse folgendermaßen zu bilden:
  • wobei new_disp' = disp + pf_disp. Falls der Vorausabrufbefehl einen Adressiermodus unterstützt, der bewirkt, daß die effektive Speicheradresse als die Summe von zwei Registerwerten berechnet wird, dann kann die Addieroperation durch Einfalten des new_disp'-Werts in Rm außerhalb des Schleifenkerns ausgelassen werden, wodurch Rm' erhalten wird, und die Rm und Rb Registeroperanden des Vorausabrufbefehls direkt spezifiziert werden, wie unten gezeigt:
  • Falls jedoch "disp" selbst ein Laufzeitwert ist, im Gegensatz zu einer einfachen Konstante, dann ist eine explizite Addieroperation unvermeidlich:
  • und falls der Vorausabrufbefehl ein Register + einenRegisteradressiermodus nicht unterstützt, werden eventuell zwei Addieroperationen benötigt:
  • Es ist jedoch darauf hinzuweisen, daß diese neuen Addierbefehle eliminiert werden können durch Registerneuzuordnung. In der Tat können der/die Vorausabrufbefehl(e) und der begünstigte Speicherreferenzbefehl in der Lage sein, durch Registerneuzuordnung das gleiche Basisregister zu verwenden, was es ermöglicht, daß die Addierbefehle gelöscht werden:
  • Rp - initialisiert zu der Adresse der Speicherposition, die durch den Ladevorgang auf der ersten Schleifeniteration referenziert wurde
  • Rm = (a_exp * net_biv_Schleife_increment)
  • Rdelta = (Rm * PFID) + pf_disp
  • Falls die Zielarchitektur ferner einen Auto- Inkrementadressiermodus (z.B. PA-RISC, IBM Power PC) unterstützt, kann das Inkrement des neuen Basisregisters Rp in den Ladebefehl selber eingefaltet werden.
  • Hinsichtlich der Codeplazierung des Vorausabrufbefehls selbst, können der/die Vorausabrufbefehl(e) zunächst benachbart zu dem begünstigten Speicherreferenzbefehl plaziert werden. Nachfolgend kann die Befehlsplanungsphase den/die Vorausabrufbefehl(e) neu ordnen, wie es nötigt ist, um die Leistungsfähigkeit zu verbessern. Dadurch können Speicherabhängigkeiten zwischen dem Vorausabrufbefehl und anderen Speicherreferenzen in dem Schleifenkern ignoriert werden, und angenommen, daß der Vorausabrufbefehl garantiert keine Ausnahme macht, kann er über Basisblocks ebenfalls frei geplant werden.

Claims (14)

1. Ein System mit einer Computereinrichtung, auf der ein Kompilierprogramm (20) läuft, mit folgenden Merkmalen:
einer Einrichtung (34) in einem Optimierer (24) auf niedriger Ebene zum Analysieren und effizienten Einfügen von expliziten Datenvorausabrufbefehlen in Schleifen von Anwendungen;
einer Indexausdruckanalyseeinrichtung (34) zum Bestimmen von Datenvorausabruferfordernissen;
einer Einrichtung (96) zum Erkennen von Cachespeicherzeilenwiederverwendungsstrukturen über Schleifeniterationen, um unnötige Vorausabrufbefehle zu eliminieren; und
einer Einrichtung (96) zum Beschränken der Einfügung von expliziten Vorausabrufbefehlen auf Situationen, in denen eine untere Grenze auf einer erreichbaren Schleifeniterationslatenzzeit als Folge der Vorausabrufbefehlseinfügung wahrscheinlich nicht erhöht wird.
2. Das System gemäß Anspruch 1, bei dem eine Analyse und eine explizite Datencachespeichervorausabrufbefehleinfügung durch den Kompilierer (20) in einem Optimierer (24) auf Maschinenbefehlebene durchgeführt werden.
3. Das System gemäß Anspruch 1 oder 2, das ferner folgendes Merkmal aufweist:
eine Einrichtung (93) zum Ausnützen von Ausführungsprofilen von vorherigen Abläufen einer Anwendung während der Einfügung von Vorausabrufbefehlen in innere Schleifen mit einem inneren Steuerfluß.
4. Das System gemäß einem der Ansprüche 1 bis 3, bei dem die Vorausabrufeinfügungseinrichtung (97) integriert ist mit anderen Optimierungsphasen auf niedriger Ebene, wobei die anderen Optimierungsphasen auf niedriger Ebene entweder ein Schleifenentrollen, eine Registerneuzuordnung oder eine Befehlsplanung umfassen.
5. Ein Verfahren zum Mildern oder Eliminieren von Cachespeicherfehlschlägen in einem Optimierer auf niedriger Ebene, das folgende Schritte umfaßt:
Durchführen einer Schleifenkernanalyse;
Entrollen von Schleifen, um den Vorausabrufbefehlsmehraufwand zu verringern;
Identifizieren von einheitlich erzeugten Äquivalenzklassen von Speicherreferenzen in einem Codestrom, wobei die Äquivalenzklassen nicht zusammenhängende Sätze von Speicherreferenzen repräsentieren, die in einer Schleife auftreten, deren Adressausdrücke als eine lineare Funktion der gleichen Basisschleifeninduktionsvariable ausgedrückt werden können und von denen bekannt ist, daß sie sich nur durch eine Kompilierzeitkonstante unterscheiden, wobei die Erfassung einer Gruppen-Raum- und Gruppen-Zeit-Lokalität unter den unterschiedlichen Speicherreferenzen möglich ist;
Berechnen eines effektiven Speicherschritts für jede der Äquivalenzklassen;
Bestimmen der Anzahl von Vorausabrufbefehlen, die für eine vollständige Cachespeicherfehlschlagabdeckung für jede Äquivalentklasse benötigt werden, wobei die Anzahl von Vorausabrufbefehlen, die eingefügt werden müssen, eine Funktion des Stils des gewünschten Vorausabrufens ist, einschließlich eines Stumm- Vorausabrufens, das für jede Speicherreferenz einen expliziten Vorausabrufbefehl einfügt, eines Basiszeilenvorausabrufens, das so viele Vorausabrufbefehle wie möglich einfügt, ohne die minimale Ressourcenschleifeniterationslatenzzeit zu beeinträchtigen, und eines selektiven Vorausabrufens, das so viele Vorausabrufbefehle einfügt, die erforderlich sind, um eine vollständige Cachespeicherfehlschlagabdeckung sicherzustellen, wobei jede Gruppen-Raum- oder Gruppen-Zeit- Lokalität ausgenützt wird, die unter Speicherreferenzen innerhalb einer gleichförmig erzeugten Äquivalenzklasse auftreten kann; und
Einfügen identifizierter Vorausabrufbefehle in den Codestrom.
6. Das Verfahren gemäß Anspruch 5, das ferner folgenden Schritt umfaßt:
Schätzen eines Vorausabrufiterationsabstands für eine Schleife als das Verhältnis einer durchschnittlichen Fehlschlaglatenzzeit und einer durchschnittlichen Schleifeniterationslatenzzeit, wobei die durchschnittliche Schleifeniterationslatenzzeit von einer Ressourcen-beschränkten unteren Grenze auf einer Zykluszahl auf der Basis von einer Maschinenressourcenverwendung abgeleitet ist.
7. Das Verfahren gemäß Anspruch 5 oder 6, das ferner folgenden Schritt umfaßt:
Einsetzen eines festen Konstantenwerts statt unbekannter Begriffe in die Adressausdrücke für Speicherreferenzen zu Laufzeit-dimensionierten Arrays, um ein Aufteilen solcher Referenzen in nicht zusammenhängende Äquivalenzklassen zu ermöglichen.
8. Das Verfahren gemäß einem der Ansprüche 5 bis 7, das ferner folgenden Schritt umfaßt:
Bestimmen der Anzahl von Vorausabrufbefehlen, die für jede einheitlich erzeugte Äquivalenzklasse für eine selektive Vorausabrufstrategie benötigt werden.
9. Das Verfahren gemäß einem der Ansprüche 5 bis 8, das ferner folgenden Schritt umfaßt:
Sortieren der Adressausdrücke für Speicherreferenzen, die zu einer Äquivalenzklasse gehören, auf der Basis der relativen Konstantenunterschiede.
10. Das Verfahren gemäß einem der Ansprüche 5 bis 9, das ferner folgenden Schritt umfaßt:
Bestimmen eines effektiven Speicherschritts für die Speicherreferenzen, die jeder Äquivalenzklasse zugeordnet sind, und Klassifizieren des effektiven Speicherschritts als entweder groß oder klein, basierend darauf, ob derselbe größer ist als die Cachespeicherzeilengröße.
11. Das Verfahren gemäß einem der Ansprüche 5 bis 10, das ferner folgenden Schritt umfaßt:
Bestimmen des Vorausabrufspeicherabstands für die Speicherreferenzen, die jeder Äquivalenzklasse zugeordnet sind, als das Produkt des effektiven Speicherschritts und des Vorausabrufiterationsabstands für die Schleife.
12. Das Verfahren gemäß einem der Ansprüche 5 bis 11, das ferner folgende Schritte umfaßt:
Entfernen von Speicherreferenzen innerhalb einer Kleinschritt-Äquivalenzklasse, die anderen Speicherreferenzen innerhalb der Äquivalenzklasse um weniger als den Vorausabrufspeicherabstand nachlaufen, wobei Speicherreferenzen, die übrigbleiben, Clusterführer sind;
Gruppieren der Speicherreferenzen, die zu einer Großschritt-Äquivalenzklasse gehören, die durch ihre Konstantadressausdruckunterschiede sortiert sind, iri Cluster, von denen jeder eine bestimmten Speicherreferenz, die als der Clusterführer bezeichnet ist, und Null oder mehr Speicherreferenzen umfaßt, die als Clusternachläufer bezeichnet werden; und
Verschmelzen von Clustern, die durch ihre Führer dargestellt werden, um die Gruppen-Zeit-Lokalität in einer paarweisen Art lohnend auszunutzen.
13. Das Verfahren gemäß einem der Ansprüche 5 bis 12, das ferner folgenden Schritt umfaßt:
Entscheiden, welche Äquivalenzklassen Vorausabrufbefehle einfügen, für eine Vorausabrufstrategie unter der Basislinie, indem zunächst einheitlich erzeugte Äquivalenzklassen auf der Basis eines Kriteriums der Vorausabrufkosten/des erwarteten Nutzens sortiert werden, und nur Zulassen, daß Vorausabrufbefehle für diejenigen Äquivalenzklassen mit dem besten Kosten erwarteter Nutzen-Verhältnis eingefügt werden, ohne zu bewirken, daß eine Ressourcen-basierte minimale Schleifeniterationslatenzzeit überschritten wird.
14. Das Verfahren gemäß einem der Ansprüche 5 bis 13, das ferner die folgenden Schritte umfaßt:
Laufen durch Cluster in jeder Äquivalenzklasse;
Erzeugen expliziter Vorausabrufbefehle für jeden Cluster; und
Einfügen der Vorausabrufbefehle in den Codestrom.
DE69615445T 1995-05-18 1996-05-15 Kompilierer zur Verbesserung der Leistung von Datencachespeichern Expired - Fee Related DE69615445T2 (de)

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
US08/443,653 US5704053A (en) 1995-05-18 1995-05-18 Efficient explicit data prefetching analysis and code generation in a low-level optimizer for inserting prefetch instructions into loops of applications

Publications (2)

Publication Number Publication Date
DE69615445D1 DE69615445D1 (de) 2001-10-31
DE69615445T2 true DE69615445T2 (de) 2002-05-02

Family

ID=23761662

Family Applications (1)

Application Number Title Priority Date Filing Date
DE69615445T Expired - Fee Related DE69615445T2 (de) 1995-05-18 1996-05-15 Kompilierer zur Verbesserung der Leistung von Datencachespeichern

Country Status (3)

Country Link
US (1) US5704053A (de)
EP (1) EP0743598B1 (de)
DE (1) DE69615445T2 (de)

Families Citing this family (127)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP3218932B2 (ja) * 1995-07-06 2001-10-15 株式会社日立製作所 データプリフェッチコード生成方法
US6742108B1 (en) * 1995-12-29 2004-05-25 Intel Corporation Method and apparatus for executing load instructions speculatively
US6301652B1 (en) * 1996-01-31 2001-10-09 International Business Machines Corporation Instruction cache alignment mechanism for branch targets based on predicted execution frequencies
US6055621A (en) * 1996-02-12 2000-04-25 International Business Machines Corporation Touch history table
US6065100A (en) * 1996-11-12 2000-05-16 Micro-Design International Caching apparatus and method for enhancing retrieval of data from an optical storage device
US5822593A (en) * 1996-12-06 1998-10-13 Xerox Corporation High-level loop fusion
JPH10228382A (ja) * 1997-02-14 1998-08-25 Nec Corp コンパイル方式
US5933643A (en) * 1997-04-17 1999-08-03 Hewlett Packard Company Profiler driven data prefetching optimization where code generation not performed for loops
JP3546341B2 (ja) * 1997-04-17 2004-07-28 株式会社日立製作所 多重ループ向けデータプリフェッチ方法およびプログラム生成方法
US6139199A (en) * 1997-06-11 2000-10-31 Sun Microsystems, Inc. Fast just-in-time (JIT) scheduler
US6088525A (en) * 1997-06-19 2000-07-11 Hewlett-Packard Company Loop profiling by instrumentation
US6035125A (en) * 1997-07-25 2000-03-07 International Business Machines Corporation Method and system for generating compact code for the loop unrolling transformation
US6535961B2 (en) * 1997-11-21 2003-03-18 Intel Corporation Spatial footprint prediction
US5964867A (en) * 1997-11-26 1999-10-12 Digital Equipment Corporation Method for inserting memory prefetch operations based on measured latencies in a program optimizer
DE69739404D1 (de) * 1997-12-10 2009-06-25 Hitachi Ltd Optimiertes speicherzugriffsverfahren
US6047390A (en) * 1997-12-22 2000-04-04 Motorola, Inc. Multiple context software analysis
WO1999034356A2 (en) * 1997-12-30 1999-07-08 Genesis One Technologies, Inc. Disk cache enhancer with dynamically sized read request based upon current cache hit rate
US5948095A (en) * 1997-12-31 1999-09-07 Intel Corporation Method and apparatus for prefetching data in a computer system
US6247174B1 (en) * 1998-01-02 2001-06-12 Hewlett-Packard Company Optimization of source code with embedded machine instructions
US6282706B1 (en) * 1998-02-10 2001-08-28 Texas Instruments Incorporated Cache optimization for programming loops
US6202204B1 (en) * 1998-03-11 2001-03-13 Intel Corporation Comprehensive redundant load elimination for architectures supporting control and data speculation
US6892173B1 (en) * 1998-03-30 2005-05-10 Hewlett-Packard Development Company, L.P. Analyzing effectiveness of a computer cache by estimating a hit rate based on applying a subset of real-time addresses to a model of the cache
US6223276B1 (en) * 1998-03-31 2001-04-24 Intel Corporation Pipelined processing of short data streams using data prefetching
US6341370B1 (en) * 1998-04-24 2002-01-22 Sun Microsystems, Inc. Integration of data prefetching and modulo scheduling using postpass prefetch insertion
US6260116B1 (en) * 1998-07-01 2001-07-10 International Business Machines Corporation System and method for prefetching data
US6253306B1 (en) 1998-07-29 2001-06-26 Advanced Micro Devices, Inc. Prefetch instruction mechanism for processor
JP3741870B2 (ja) * 1998-08-07 2006-02-01 富士通株式会社 命令及びデータの先読み方法、マイクロコントローラ、疑似命令検出回路
US6401193B1 (en) 1998-10-26 2002-06-04 Infineon Technologies North America Corp. Dynamic data prefetching based on program counter and addressing mode
US6341371B1 (en) * 1999-02-23 2002-01-22 International Business Machines Corporation System and method for optimizing program execution in a computer system
US6367071B1 (en) * 1999-03-02 2002-04-02 Lucent Technologies Inc. Compiler optimization techniques for exploiting a zero overhead loop mechanism
US6477654B1 (en) * 1999-04-06 2002-11-05 International Business Machines Corporation Managing VT for reduced power using power setting commands in the instruction stream
US6321330B1 (en) * 1999-05-28 2001-11-20 Intel Corporation Each iteration array selective loop data prefetch in multiple data width prefetch system using rotating register and parameterization to avoid redundant prefetch
US6820250B2 (en) * 1999-06-07 2004-11-16 Intel Corporation Mechanism for software pipelining loop nests
US6496921B1 (en) 1999-06-30 2002-12-17 International Business Machines Corporation Layered speculative request unit with instruction optimized and storage hierarchy optimized partitions
US6421763B1 (en) 1999-06-30 2002-07-16 International Business Machines Corporation Method for instruction extensions for a tightly coupled speculative request unit
US6393528B1 (en) * 1999-06-30 2002-05-21 International Business Machines Corporation Optimized cache allocation algorithm for multiple speculative requests
US6532521B1 (en) 1999-06-30 2003-03-11 International Business Machines Corporation Mechanism for high performance transfer of speculative request data between levels of cache hierarchy
US6421762B1 (en) 1999-06-30 2002-07-16 International Business Machines Corporation Cache allocation policy based on speculative request history
US6510494B1 (en) 1999-06-30 2003-01-21 International Business Machines Corporation Time based mechanism for cached speculative data deallocation
US6360299B1 (en) * 1999-06-30 2002-03-19 International Business Machines Corporation Extended cache state with prefetched stream ID information
BR9902725A (pt) * 1999-07-13 2001-03-06 Coppe Ufrj Processo de formação, memorização e reuso, em tempo de execução, de sequências de instruções dinâmicas em computadores
US6651088B1 (en) * 1999-07-20 2003-11-18 Hewlett-Packard Development Company, L.P. Method for reducing coherent misses in shared-memory multiprocessors utilizing lock-binding prefetchs
US6813251B1 (en) * 1999-07-27 2004-11-02 Intel Corporation Split Transaction protocol for a bus system
US6675374B2 (en) * 1999-10-12 2004-01-06 Hewlett-Packard Development Company, L.P. Insertion of prefetch instructions into computer program code
US6421826B1 (en) 1999-11-05 2002-07-16 Sun Microsystems, Inc. Method and apparatus for performing prefetching at the function level
US6427235B1 (en) 1999-11-05 2002-07-30 Sun Microsystems, Inc. Method and apparatus for performing prefetching at the critical section level
US6560693B1 (en) 1999-12-10 2003-05-06 International Business Machines Corporation Branch history guided instruction/data prefetching
US6848029B2 (en) 2000-01-03 2005-01-25 Dirk Coldewey Method and apparatus for prefetching recursive data structures
US6564297B1 (en) * 2000-06-15 2003-05-13 Sun Microsystems, Inc. Compiler-based cache line optimization
US20060206874A1 (en) * 2000-08-30 2006-09-14 Klein Dean A System and method for determining the cacheability of code at the time of compiling
US6651245B1 (en) * 2000-10-03 2003-11-18 Sun Microsystems, Inc. System and method for insertion of prefetch instructions by a compiler
US7107583B2 (en) * 2001-02-16 2006-09-12 Hewlett-Packard Development Company, L.P. Method and apparatus for reducing cache thrashing
US7653710B2 (en) 2002-06-25 2010-01-26 Qst Holdings, Llc. Hardware task manager
US6836839B2 (en) 2001-03-22 2004-12-28 Quicksilver Technology, Inc. Adaptive integrated circuitry with heterogeneous and reconfigurable matrices of diverse and adaptive computational units having fixed, application specific computational elements
US7752419B1 (en) 2001-03-22 2010-07-06 Qst Holdings, Llc Method and system for managing hardware resources to implement system functions using an adaptive computing architecture
US8843928B2 (en) 2010-01-21 2014-09-23 Qst Holdings, Llc Method and apparatus for a general-purpose, multiple-core system for implementing stream-based computations
US7962716B2 (en) 2001-03-22 2011-06-14 Qst Holdings, Inc. Adaptive integrated circuitry with heterogeneous and reconfigurable matrices of diverse and adaptive computational units having fixed, application specific computational elements
US20040133745A1 (en) * 2002-10-28 2004-07-08 Quicksilver Technology, Inc. Adaptable datapath for a digital processing system
US6721943B2 (en) * 2001-03-30 2004-04-13 Intel Corporation Compile-time memory coalescing for dynamic arrays
US6577678B2 (en) 2001-05-08 2003-06-10 Quicksilver Technology Method and system for reconfigurable channel coding
US7191430B2 (en) * 2001-09-24 2007-03-13 Hewlett-Packard Development Company, L.P. Providing instruction execution hints to a processor using break instructions
US6959435B2 (en) * 2001-09-28 2005-10-25 Intel Corporation Compiler-directed speculative approach to resolve performance-degrading long latency events in an application
JP2003108386A (ja) * 2001-09-28 2003-04-11 Hitachi Ltd 間接参照データプリフェッチ方法
EP1444571B1 (de) * 2001-10-08 2007-12-12 Telefonaktiebolaget LM Ericsson (publ) Hidden-job-startpräperation in einem anweisungsparallelen prozessorsystem
US7257810B2 (en) * 2001-11-02 2007-08-14 Sun Microsystems, Inc. Method and apparatus for inserting prefetch instructions in an optimizing compiler
US7234136B2 (en) * 2001-11-02 2007-06-19 Sun Microsystems, Inc. Method and apparatus for selecting references for prefetching in an optimizing compiler
US7046635B2 (en) 2001-11-28 2006-05-16 Quicksilver Technology, Inc. System for authorizing functionality in adaptable hardware devices
US6986021B2 (en) 2001-11-30 2006-01-10 Quick Silver Technology, Inc. Apparatus, method, system and executable module for configuration and operation of adaptive integrated circuitry having fixed, application specific computational elements
US8412915B2 (en) 2001-11-30 2013-04-02 Altera Corporation Apparatus, system and method for configuration of adaptive integrated circuitry having heterogeneous computational elements
US7215701B2 (en) 2001-12-12 2007-05-08 Sharad Sambhwani Low I/O bandwidth method and system for implementing detection and identification of scrambling codes
CA2365375A1 (en) * 2001-12-18 2003-06-18 Ibm Canada Limited-Ibm Canada Limitee Optimizing source code for iterative execution
US20030126591A1 (en) * 2001-12-21 2003-07-03 Youfeng Wu Stride-profile guided prefetching for irregular code
US7403981B2 (en) * 2002-01-04 2008-07-22 Quicksilver Technology, Inc. Apparatus and method for adaptive multimedia reception and transmission in communication environments
US20030204840A1 (en) * 2002-04-30 2003-10-30 Youfeng Wu Apparatus and method for one-pass profiling to concurrently generate a frequency profile and a stride profile to enable data prefetching in irregular programs
US7328414B1 (en) 2003-05-13 2008-02-05 Qst Holdings, Llc Method and system for creating and programming an adaptive computing engine
US7660984B1 (en) 2003-05-13 2010-02-09 Quicksilver Technology Method and system for achieving individualized protected space in an operating system
US20040006667A1 (en) * 2002-06-21 2004-01-08 Bik Aart J.C. Apparatus and method for implementing adjacent, non-unit stride memory access patterns utilizing SIMD instructions
US6934865B2 (en) * 2002-07-09 2005-08-23 University Of Massachusetts Controlling a processor resource based on a compile-time prediction of number of instructions-per-cycle that will be executed across plural cycles by the processor
US6970985B2 (en) 2002-07-09 2005-11-29 Bluerisc Inc. Statically speculative memory accessing
US7278136B2 (en) * 2002-07-09 2007-10-02 University Of Massachusetts Reducing processor energy consumption using compile-time information
US8108656B2 (en) 2002-08-29 2012-01-31 Qst Holdings, Llc Task definition for specifying resource requirements
US7937591B1 (en) 2002-10-25 2011-05-03 Qst Holdings, Llc Method and system for providing a device which can be adapted on an ongoing basis
US8276135B2 (en) 2002-11-07 2012-09-25 Qst Holdings Llc Profiling of software and circuit designs utilizing data operation analyses
US20040093591A1 (en) * 2002-11-12 2004-05-13 Spiros Kalogeropulos Method and apparatus prefetching indexed array references
US7225301B2 (en) 2002-11-22 2007-05-29 Quicksilver Technologies External memory controller node
WO2004057501A2 (en) * 2002-12-17 2004-07-08 Cadence Design Systems, Inc. Method and system for implementing circuit simulators
JP2004303113A (ja) * 2003-04-01 2004-10-28 Hitachi Ltd 階層メモリ向け最適化処理を備えたコンパイラおよびコード生成方法
US7624387B2 (en) * 2003-04-10 2009-11-24 Panasonic Corporation Compiler, program product, compilation device, communication terminal device, and compilation method
US7185323B2 (en) * 2003-05-16 2007-02-27 Sun Microsystems, Inc. Using value speculation to break constraining dependencies in iterative control flow structures
US7308681B2 (en) * 2003-10-28 2007-12-11 International Business Machines Corporation Control flow based compression of execution traces
US20050114850A1 (en) 2003-10-29 2005-05-26 Saurabh Chheda Energy-focused re-compilation of executables and hardware mechanisms based on compiler-architecture interaction and compiler-inserted control
US7996671B2 (en) 2003-11-17 2011-08-09 Bluerisc Inc. Security of program executables and microprocessors based on compiler-architecture interaction
CA2453685A1 (en) * 2003-12-17 2005-06-17 Ibm Canada Limited - Ibm Canada Limitee Method and system for code modification based on cache structure
US7389385B2 (en) * 2003-12-19 2008-06-17 Intel Corporation Methods and apparatus to dynamically insert prefetch instructions based on compiler and garbage collector analysis
US20050149915A1 (en) * 2003-12-29 2005-07-07 Intel Corporation Methods and apparatus for optimizing a program undergoing dynamic binary translation using profile information
US8607209B2 (en) 2004-02-04 2013-12-10 Bluerisc Inc. Energy-focused compiler-assisted branch prediction
WO2005078579A1 (ja) * 2004-02-12 2005-08-25 Matsushita Electric Industrial Co., Ltd. プログラム変換装置およびプログラム変換方法
US7168070B2 (en) * 2004-05-25 2007-01-23 International Business Machines Corporation Aggregate bandwidth through management using insertion of reset instructions for cache-to-cache data transfer
US7971191B2 (en) * 2004-06-10 2011-06-28 Hewlett-Packard Development Company, L.P. System and method for analyzing a process
US7493609B2 (en) * 2004-08-30 2009-02-17 International Business Machines Corporation Method and apparatus for automatic second-order predictive commoning
US7849453B2 (en) * 2005-03-16 2010-12-07 Oracle America, Inc. Method and apparatus for software scouting regions of a program
US7681188B1 (en) * 2005-04-29 2010-03-16 Sun Microsystems, Inc. Locked prefetch scheduling in general cyclic regions
US7421540B2 (en) * 2005-05-03 2008-09-02 International Business Machines Corporation Method, apparatus, and program to efficiently calculate cache prefetching patterns for loops
US20070130114A1 (en) * 2005-06-20 2007-06-07 Xiao-Feng Li Methods and apparatus to optimize processing throughput of data structures in programs
US7793278B2 (en) * 2005-09-30 2010-09-07 Intel Corporation Systems and methods for affine-partitioning programs onto multiple processing units
US7757222B2 (en) * 2005-09-30 2010-07-13 Intel Corporation Generating efficient parallel code using partitioning, coalescing, and degenerative loop and guard removal
US7784037B2 (en) * 2006-04-14 2010-08-24 International Business Machines Corporation Compiler implemented software cache method in which non-aliased explicitly fetched data are excluded
US7865885B2 (en) * 2006-09-27 2011-01-04 Intel Corporation Using transactional memory for precise exception handling in aggressive dynamic binary optimizations
US20080126766A1 (en) 2006-11-03 2008-05-29 Saurabh Chheda Securing microprocessors against information leakage and physical tampering
EP2798470A4 (de) * 2011-12-29 2015-07-15 Intel Corp Verwaltete befehlscachespeicher-vorabladung
US9043579B2 (en) 2012-01-10 2015-05-26 International Business Machines Corporation Prefetch optimizer measuring execution time of instruction sequence cycling through each selectable hardware prefetch depth and cycling through disabling each software prefetch instruction of an instruction sequence of interest
US9164743B2 (en) * 2012-07-02 2015-10-20 International Business Machines Corporation Strength reduction compiler optimizations for operations with unknown strides
US9411558B2 (en) 2012-10-20 2016-08-09 Luke Hutchison Systems and methods for parallelization of program code, interactive data visualization, and graphically-augmented code editing
JP2014112327A (ja) * 2012-12-05 2014-06-19 Fujitsu Ltd 変換プログラム、変換装置及び変換方法
US9547553B1 (en) 2014-03-10 2017-01-17 Parallel Machines Ltd. Data resiliency in a shared memory pool
US9781027B1 (en) 2014-04-06 2017-10-03 Parallel Machines Ltd. Systems and methods to communicate with external destinations via a memory network
US9594688B1 (en) 2014-12-09 2017-03-14 Parallel Machines Ltd. Systems and methods for executing actions using cached data
US9690713B1 (en) 2014-04-22 2017-06-27 Parallel Machines Ltd. Systems and methods for effectively interacting with a flash memory
US9529622B1 (en) 2014-12-09 2016-12-27 Parallel Machines Ltd. Systems and methods for automatic generation of task-splitting code
US9213531B2 (en) * 2014-05-01 2015-12-15 Google Inc. Methods to eliminate extra memory loads while accessing global variables in position independent code
US9639473B1 (en) 2014-12-09 2017-05-02 Parallel Machines Ltd. Utilizing a cache mechanism by copying a data set from a cache-disabled memory location to a cache-enabled memory location
US9753873B1 (en) 2014-12-09 2017-09-05 Parallel Machines Ltd. Systems and methods for key-value transactions
US9781225B1 (en) 2014-12-09 2017-10-03 Parallel Machines Ltd. Systems and methods for cache streams
US9632936B1 (en) 2014-12-09 2017-04-25 Parallel Machines Ltd. Two-tier distributed memory
US11989254B2 (en) * 2020-09-10 2024-05-21 Taboola.Com Ltd. Semantic meaning association to components of digital content
CN114327643B (zh) * 2022-03-11 2022-06-21 上海聪链信息科技有限公司 机器指令预处理方法、电子设备及计算机可读存储介质
CN117707995B (zh) * 2024-02-02 2024-04-26 北京惠朗时代科技有限公司 一种数据预读取的优化装置及操作方法

Family Cites Families (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5214766A (en) * 1989-04-28 1993-05-25 International Business Machines Corporation Data prefetching based on store information in multi-processor caches
US5193167A (en) * 1990-06-29 1993-03-09 Digital Equipment Corporation Ensuring data integrity by locked-load and conditional-store operations in a multiprocessor system
US5287467A (en) * 1991-04-18 1994-02-15 International Business Machines Corporation Pipeline for removing and concurrently executing two or more branch instructions in synchronization with other instructions executing in the execution unit
US5396604A (en) * 1991-07-12 1995-03-07 Hewlett-Packard Company System and method for reducing the penalty associated with data cache misses
US5537620A (en) * 1994-09-16 1996-07-16 International Business Machines Corporation Redundant load elimination on optimizing compilers

Also Published As

Publication number Publication date
EP0743598A2 (de) 1996-11-20
US5704053A (en) 1997-12-30
EP0743598B1 (de) 2001-09-26
EP0743598A3 (de) 1997-07-23
DE69615445D1 (de) 2001-10-31

Similar Documents

Publication Publication Date Title
DE69615445T2 (de) Kompilierer zur Verbesserung der Leistung von Datencachespeichern
DE69209888T2 (de) Befehlablaufsteuerung für einen Rechner
DE10393481B4 (de) Verfahren und Vorrichtung zum Management einer Cache-Umgehung
DE10393260T5 (de) Nachdurchgangs-Binäranpassung für eine auf Software basierende spekulative Vorberechnung
DE69030425T2 (de) Verfahren und Vorrichtung zur Kompilierung von Rechnerprogrammen mit Registerzuweisung zwischen Prozeduren
DE3650696T2 (de) Paralleles prozessorsystem und zugehöriges verfahren zur behandlung von natürlichen nebenläufigkeiten
Mueller et al. Avoiding conditional branches by code replication
DE69129919T2 (de) Verfahren zur Kompilierung von Rechnerbefehlen, um Cachespeicherleistung zu verbessern
Cann Compilation techniques for high-performance applicative computation
Liao et al. Post-pass binary adaptation for software-based speculative precomputation
Chang et al. Using profile information to assist classic code optimizations
DE69724771T2 (de) Zentralprozessoreinheit mit x86 und dsp kern und einem dsp funktions-dekoder zum abbilden von x 86-befehlen auf dsp-befehle
DE69131832T2 (de) Integrierte hierarchische darstellung von rechnerprogrammen für ein software-entwicklungssystem
DE112009000741B4 (de) Vektorbefehle zum Ermöglichen von effizienter Synchronisation und parallelen Reduktionsoperationen
DE60223990T2 (de) System zum Ausführen von Zwischenkode, Methode zum Ausführen von Zwischenkode, und Computerprogrammprodukt zum Ausführen von Zwischenkode
DE69613732T2 (de) Betriebsmittelzuweisungsgerät
DE69727453T2 (de) Kompilieren von prädikatiertem Code mit direkter Analyse desselben
DE69415126T2 (de) Gegenflusspipelineprozessor
DE102018006791A1 (de) Prozessoren, Verfahren und Systeme mit einem konfigurierbaren räumlichen Beschleuniger mit einem Sequenzer-Datenflussoperator
Fang et al. Automatic fence insertion for shared memory multiprocessing
DE112011100258T5 (de) Durchführen von aggressiven Codeoptimierungen mit einer Fähigkeit zum Annulieren derdurch die aggressiven Optimierungen vorgenommenen Änderungen
DE102014211047A1 (de) Parallelisierungskompilierverfahren, Parallelisierungskompilierer, Parallelisierungskompiliervorrichtung und Bordvorrichtung
DE112011100715T5 (de) Hardware-hilfs-thread
Talbot et al. Riposte: a trace-driven compiler and parallel VM for vector code in R
DE102009046876A1 (de) Verfahren und System für die Datenvorabholung für Schleifen auf der Basis linearer Induktionsausdrücke

Legal Events

Date Code Title Description
8364 No opposition during term of opposition
8327 Change in the person/name/address of the patent owner

Owner name: HEWLETT-PACKARD DEVELOPMENT CO., L.P., HOUSTON, TE

8339 Ceased/non-payment of the annual fee