-
Hintergrund
-
Zahlreiche Anwendungen weisen einen hohen Grad an Parallelverarbeitung auf Datenebene auf und sollten in der Lage sein, von einer Einzelbefehl-Mehrfachdaten (Single-Instruction Multiple-Data, SIMD)-Unterstützung zu profitieren. Bei einer SIMD-Ausführung arbeitet ein einzelner Befehl auf mehreren Datenelementen gleichzeitig. Dies wird typischerweise durch ein Erweitern der Breite von verschiedenen Ressourcen implementiert, wie z. B. Registern und arithmetisch logische Einheiten (ALUs), das ihnen erlaubt, mehrere Datenelemente zu halten bzw. auf ihnen zu arbeiten. Jedoch verbringen viele dieser Anwendungen eine bedeutende Zeitmenge mit atomaren Operationen auf einem Satz von dünnbesetzten Stellen und sehen somit einen beschränkten Vorteil durch SIMD, da aktuelle Architekturen atomare Vektoroperationen nicht unterstützen.
-
In zahlreichen Anwendungen werden oft Synchronisationsprimitive und parallele Reduktionsoperationen in Multiprozessorsystemen durchgeführt. Sychronisationsprimitive stellen sicher, dass ein Programm in einer korrekten Reihenfolge ausgeführt wird, wenn mehrere Threads zusammenwirkend arbeiten. Diese Primitive sind oft unter Verwendung einer atomaren Read-Modify-Write-Operation implementiert. Eine Reduktion ist eine gebräuchliche Operation, die in vielen wissenschaftlichen Anwendungen zu finden ist. Wenn mehrere Threads parallele Reduktionen durchführen, werden typischerweise atomare Read-Modify-Write-Sequenzen verwendet, um die Korrektheit in Wettlaufsituationen sicherzustellen.
-
Moderne parallele Architekturen werden mit SIMD-Einheiten ausgerüstet, um die Leistungsfähigkeit von vielen Anwendungen mit Parallelverarbeitung auf Datenebene zu verbessern. Um die SIMD-Effizienz aufrechtzuerhalten erlauben solche Architekturen nicht nur SIMD-Arithmetikoperationen, sondern auch SIMD-Speicherlesevorgänge (Memory Reads) und -schreibvorgänge (Writes) (durch Gather-Scatter-Einheiten). Jedoch unterstützt keine dieser Architekturen atomare SIMD-Operationen. Das Ergebnis besteht darin, dass diese atomaren Operationen nicht vektorisiert werden können und deshalb unter Verwendung von skalarem Code implementiert werden müssen. Dies kann die SIMD-Effizienz beträchtlich degradieren, insbesondere dann, wenn die SIMD-Breite, d.h. die Anzahl von gleichzeitig verarbeiteten Elementen, groß ist (z. B. 16).
-
Scatter-Reduktionen sind gebräuchliche Operationen in vielen Anwendungen. Eine Scatter-Add-Operation kann z. B. verwendet werden, um zu ermöglichen, dass mehrere Werte eines ersten Arrays reduziert werden in (d.h. addiert werden zu) ausgewählte(n) Elemente(n) eines zweiten Arrays gemäß einer Verteilung von Indices, die oft zufällig sein kann. Aufgrund dessen ist es schwierig, mehrere Elemente nebenläufig (d.h. im SIMD-Modus) effizient zu verarbeiten.
-
US 5,872,987 A offenbart einen stark parallelisierten Computer mit einem Hilfsvektorprozessor. Der Hilfsprozessor ist mit einem Speichermodul verbunden. Bei einem Speicherzugriff führt der Hilfsprozessor eine Speicherzugriffsoperation durch zum Speichern von Daten, die von einem anderen Prozessorkern empfangen worden sind, oder der Hilfsprozessor erlangt Daten von dem Speichermodul zur Übertragung an den anderen Prozessorknoten. Ferner wird eine Vektormaske verwendet, um die Lade/Speicher-Operationen durchzuführen.
-
US 2007/0283127 A1 offenbart ein Verfahren und eine Vorrichtung zum Laden/Addieren/Speichern von Vektoren in einem indirekt adressierten Speicher.
-
Histogrammberechnungen sind gebräuchliche Operationen in vielen Bildverarbeitungsanwendungen. Ein Histogramm wird z.B. verwendet, um die Verteilung von Farbwerten von Pixeln in einem Bild zu verfolgen. Jedoch können Aktualisierungen des Histogramm-Arrays abhängig von Eingabedaten für ein Array zufällig sein. Insbesondere können Indices von benachbarten Elementen auf dasselbe Histogramm-Bin zeigen. Diese Bedingung macht es sehr schwierig, mehrere Daten nebenläufig (d.h. im SIMD-Modus) zu verarbeiten.
-
KURZFASSUNG DER ERFINDUNG
-
Um atomare Operationen auf mehreren nicht zusammenhängenden Speicherstellen in einer SIMD-Weise effizient zu unterstützen, stellt die vorliegende Erfindung einen Prozessor nach Anspruch 1, eine Vorrichtung nach Anspruch 5 und ein System nach Anspruch 8 zur Verfügung.
-
Kurzbeschreibung der Zeichnungen
-
- 1A ist ein Blockdiagramm eines Prozessorkerns in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung.
- 1B ist eine beispielhafte Repräsentation einer Gather/Scatter-Einheit in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung.
- 2 ist ein Flussdiagramm zum Durchführen von atomaren Vektoroperationen in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung.
- 3 ist ein Blockdiagramm eines Systems in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung.
-
Detaillierte Beschreibung
-
Ausführungsformen können eine Scatter-Gather-Speicherfunktionalität erweitern, um eine Unterstützung von atomaren Vektoroperationen bereitzustellen. In verschiedenen Ausführungsformen können SIMD-Befehle bereitgestellt sein, um atomare Operationen zu ermöglichen. Speziell können ein sogenannter Gather-Linked-Vektorbefehl und ein Scatter-Conditional-Vektorbefehl bereitgestellt sein, um atomare Operationen auf mehreren nicht zusammenhängenden Speicherstellen in einer SIMD-Weise effizient zu unterstützen. Beachte, dass die Begriffe „Vektor“ und „SIMD“, so wie sie hier verwendet werden, als miteinander vertauschbar verwendet werden, um mehrere Datenelemente zu beschreiben, auf die durch einen einzelnen Befehl eingewirkt wird. Auf diese Weise können diese Befehle ermöglichen, dass atomare SIMD-Operationen Synchronisationprimitive und parallele Reduktionsoperationen effizienter implementieren. Des Weiteren können andere Vektorbefehle eine Prozessorunterstützung für prozessorinterne Reduktionsoperationen und Histogrammberechnungen bereitstellen.
-
In einer Ausführungsform kann eine Gather-Scatter-Einheit eingerichtet sein, atomare SIMD-Speicheroperationen zu erlauben. Ein effizientes Verwenden von SIMD in Anwendungen, in denen Datenstrukturen Elemente aufweisen, auf die indirekt (z. B. A[B[i]]) statt zusammenhängend zugegriffen wird, erfordert oft ein Neuanordnen von Daten, das zu einem substantiellen Overhead führen kann. Um diesen Overhead anzusprechen, kann eine Hardware-Unterstützung bereitgestellt sein, um Laden und Speichern von nicht zusammenhängenden Datenelementen in einer SIMD-Weise zu ermöglichen, um Gather/Scatter-Operationen durchzuführen. Namentlich liest (sammelt) eine Gather-Operation mehrere Datenelemente von indirekt addressierten Stellen basierend auf Adressen, die in dem SIMD-Quellregister enthalten sind, und packt sie in ein einziges SIMD-Register. Umgekehrt entpackt eine Scatter-Operation die Elemente in einem SIMD-Registers und schreibt (streut) sie in einen Satz von indirekt adressierten Stellen.
-
Speziell enthält ein Gather-Linked-Befehl in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung Reservierungen für die Stellen, die gesammelt werden, und ein Scatter-Conditional-Befehl in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung wird nur Werte auf Elemente streuen, deren entsprechende Reservierungen noch gehalten werden. Da ein Scatter-Conditional nur für eine Untermenge der Elemente (oder für überhaupt keines) erfolgreich sein kann, hat der Befehl eine Ausgabemaske, die analog zu der Ausgabe eines Store-Conditionals Erfolg oder Fehlschlag anzeigt. Eine Ausgabemaske für den Gather-Linked-Befehl kann mehr Flexibilität bei Hardware-Implementierungen erlauben. Ausführungsformen können skalare atomare Speicheroperationen erweitern, namentlich ein Paar von skalaren Befehlen, die Load-Linked (LL) und Store-Conditional (SC) genannt werden. LL gibt den Wert zurück, der an einer gemeinsamen Stelle gespeichert ist, und setzt einen Reservierungsindikator, der der Stelle zugeordnet ist. SC prüft den Reservierungsindikator. Falls er gültig ist, wird ein neuer Wert auf die Stelle geschrieben und die Operation gibt Erfolg zurück, sonst wird der Wert nicht geschrieben und die Operation gibt ein Flag zurück, das Fehlschlag anzeigt. Konzeptuell ist dort für jede gemeinsame Speicherstelle, für jeden Hardware-Kontext, ein Reservierungsbit vorhanden; die Reservierungsbits, die einer gemeinsamen Speicherstelle zugeordnet sind, werden gelöscht, wenn auf diese Stelle durch einen beliebigen Hardware-Kontext geschrieben wird. Eine Verwendung von LL und SC besteht beim Implementieren von Synchronisationsprimitiven einer höheren Ebene, wie z. B. Lock und Unlock. Locks werden verwendet, um Atomarität von Zugriffen auf gemeinsamen Daten durch mehrere Threads sicherzustellen. Jedoch arbeiten diese Befehle nur auf einem einzigen Element zur gleichen Zeit. Ausführungsformen können verwendet werden, um diese Beschränkung dieser Befehle zu überwinden.
-
In einer SIMD-Architektur können bis zu VLEN (SIMD-Vektorlänge)-Aktualisierungen von VLEN Stellen unter Verwendung von SIMD parallel ausgeführt werden, wenn von ihnen bekannt ist, dass sie unterschiedliche Speicherstellen aktualisieren. Jedoch erfordert ein Garantieren der Atomarität von VLEN gleichzeitigen Aktualisierungen ein Erlangen und Freigeben von VLEN Locks. Wenn skalare Instruktionen verwendet werden, werden VLEN Iterationen einer Schleife ausgeführt, um VLEN Datenelemente zu detektieren, zu erlangen, zu aktualisieren und die Locks freizugeben, und verschiedene Overheads sind solchen Operationen zugeordnet.
-
Eine andere gebräuchliche Operation in vielen Anwendungen ist eine Reduktionsoperation. In Multiprozessorsystemen kann eine Reduktion durch mehrere Threads durchgeführt werden, um die Leistungsfähigkeit zu verbessern. Jedoch wird in einer parallelen Implementierung ein atomarer Zugriff auf eine gemeinsame Datenstruktur verwendet, um die Korrektheit sicherzustellen, wenn mehrere Threads gleichzeitig dieselbe Speicherstelle aktualisieren. Somit kann eine Reduktionsoperation skalare Load-Linked- und Store-Conditional-Befehle verwenden, um Atomarität von gleichzeitigen Aktualisierungen sicherzustellen; jedoch können solche Operationen ohne eine Ausführungsform der vorliegenden Erfindung nicht in einer SIMD-Weise ausgeführt werden.
-
Effiziente SIMD-freundliche Implementierungen von Synchronisationsprimitiven und paralleler Reduktion können in verschiedenen Ausführungsformen durch Bereitstellen einer SIMD-Unterstützung für LL- und SC-Befehle realisiert sein. Um die SIMD-Effizienz von Synchronisationsprimitiven und parallelen Reduktionen zu verbessern, können, genauer gesagt, zwei Befehle, ein Gather-Linked (vgatherlink)-Befehl und ein Scatter-Conditional (vscattercond)-Befehl, Load-Linked- und Store-Conditional-Operationen für SIMD-Architekturen ermöglichen. Zusätzlich können ein Gather-Vektorbefehl (vgather) und ein Scatter (vscatter)-Vektorbefehl, die in einer SIMD-Architektur verfügbar sind, wirksam eingesetzt werden. Der Gather-Vektorbefehl kann wie folgt sein:
- vgather base, Addr, Dst
- welcher verursacht, dass VLEN Datenelemente aus VLEN (nicht notwendigerweise zusammenhängenden und möglicherweise duplizierten) Speicherstellen gesammelt werden, deren Adressen aus base und Addr (base[Addr[0]], ..., base[Addr[VLEN-1]]) berechnet werden und
- zusammenhängend in das Ziel, Dst, gespeichert werden. Beachte, dass Addr und Dst entweder im Speicher oder einem SIMD-Register sein können. Der Scatter-Vektorbefehl kann wie folgt sein:
-
Dieser Befehl streut VLEN zusammenhängende Datenelemente aus einer Quelle, Scr, in VLEN (nicht notwendigerweise zusammenhängende, jedoch eindeutige) Speicherstellen, deren Adressen in einem Adressoperanden, Addr, gespeichert sind. Wie im Fall des vgather-Befehls können Addr und Src entweder im Speicher oder in einem SIMD-Register sein.
-
Basierend auf diesen zwei Vektorbefehlen und skalaren LL- und SC-Befehlen kann somit ein Gather-Linked-Vektorbefehl, vgatherlink, wie folgt definiert sein:
Opcode | Ziel | Basis | Quelle | ask |
vgatherlink | Dst | Speicher | Addr | |
-
Dieser Befehl wird tätig, um mehrere Datenelemente zu sammeln und zu verlinken und ebenfalls um die Speicherstellen der gesammelten Datenelemente, die von einem späteren Scatter-Conditional-Befehl verwendet werden sollen, zu reservieren. Der Befehl versucht somit, bis zu VLEN Speicherstellen, memory[Addr[0]], memory[Addr[VLEN-1]], in ein Ziel, Dst, gemäß einer Maske zu sammeln und zu verlinken. Er kann beim Sammeln und Verlinken einiger der Datenelemente fehlschlagen. Falls dem so ist, sammelt er und verlinkt nur eine Untermenge von VLEN Speicherstellen und setzt die entsprechenden Bits der Maske F auf einen gültigen Zustand, z. B. einen „1"-Zustand. Die fehlgeschlagenen Elemente werden ihre entsprechende Maske F auf einen ungültigen Zustand, z. B. einen „0“-Zustand, gesetzt haben.
-
Ähnlich kann vscattercond wie folgt definiert sein:
Opcode | Quelle | Basis | Ziel | ask |
vscattercond | Src | Speicher | Addr | |
-
Dieser Befehl wird tätig, um mehrere Datenelemente auf einen Speicher bedingt zu streuen, und insbesondere nur auf die Speicherstellen, die von dem vgatherlink-Befehl reserviert sind und deren Reservierungen noch gültig sind (d.h., seit dem vgatherlink fanden keine Schreibvorgänge auf diese Stelle statt). Der Befehl streut somit bedingt bis zu VLEN Datenelemente aus einer Quelle, Src, in VLEN Speicherstellen, memory[Addr[0]], ..., memory[Addr[VLEN-1]], gemäß einer Maske, F. Für alle Elemente gemäß der Maske, für die die individuelle Scatter-Conditional-Operation fehlgeschlagen ist, werden die entsprechenden Elemente der Maske F auf einen ungültigen Zustand, z. B. einen „0“-Zustand, gesetzt.
-
Unter Verwendung einer Kombination von vgatherlink- und vscattercond-Befehlen und Maskenmanipulationen (siehe unten), kann eine Untermenge von VLEN atomaren Operationen (z. B. Erlangen einer Untermenge von VLEN Locks) durchgeführt werden und die entsprechenden Maskenelemente auf 1 gesetzt werden. Diese Maske kann verwendet werden, um sicher im SIMD-Bereich auszuführen, da nur die Untermenge von SIMD-Elementen gemäß der Maske, die den erfolgreichen atomaren Operationen entsprechen, aktiviert sein wird. Nun Bezug nehmend auf Tabelle 1 wird ein Beispiel-Code-Segment gezeigt, das vgatherlink und vscattercond verwendet, um eine Untermenge von VLEN Locks zu erlangen und freizugeben.
Der obige Code aktualisiert eine Untermenge von VLEN SIMD-Elementen gemäß einer Maske in jeder Iteration der While-Schleife, bis alle VLEN Elemente aktualisiert sind. Die SIMD-Elemente gemäß der Maske werden automatisch aktualisiert. Beachte, dass es möglich ist, dass aufgrund einer Lock-Konkurrenzsituation mit anderen Threads keine Locks in einer gegebenen Iteration der While-Schleife erlangt werden. Dies wird dazu führen, dass der SIMD_update-Bereich gemäß einer Maske ausführt, in der sich alle Elemente in einem „ungültig“-Zustand befinden, als eine No-Operation (NOP) tätig sind. Da nur eine Untermenge von Locks gemäß einer Maske erlangt wird, ist kein Sortieren von Locks erforderlich. Das Sortieren von Locks würde typischerweise in der entsprechenden seriellen Implementierung des kritischen Abschnitts verwendet werden, um Deadlocks zu vermeiden. Das Sortieren von Locks kann in der seriellen Implementierung auf Kosten von komplizierterem und ineffizienterem Code vermieden werden. In dem obigen Code kann ein Deadlock lediglich durch ein Erlangen von nicht umkämpften Locks und ein Fortschreiten mit der Ausführung verhindert werden. Eine beispielhafte Implementierung dieses Codes wird unten mit Bezug auf
2 beschrieben.
-
Beachte, dass die Definition der vgatherlink- und vscattercond-Befehle flexibel ist und unterschiedliche Verwendungsszenarien ermöglichen kann. Wir könnten z. B. stattdessen in dem obigen Code zuerst iterieren, um die Locks zu erlangen, bis alle VLEN Locks erlangt wurden, und dann alle VLEN Aktualisierungen gleichzeitig durchführen.
-
Beachte, dass während ein skalarer Load-Linked-Befehl immer erfolgreich ist, ist einem vgatherlink-Befehl in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung erlaubt, auf einer Untermenge von Adressen fehlzuschlagen. Ein Fehlschlag kann aus zahlreichen Gründen erfolgen, z. B.: (1) andere Threads haben die Untermenge von Adressen verlinkt; (2) ein Konflikt im Cache: falls der einzige Weg, eine neue Zeile herzubringen, darin besteht, eine andere verlinkte Zeile hinauszuwerfen (z. B. aufgrund von eingeschränkter Assoziativität); und (3) die Zeile ist an einer entfernten Stelle oder im Speicher und wird eine lange Latenz beanspruchen, um geholt zu werden (z. B. ein Cache-Miss tritt auf).
-
Es gibt dort zahlreiche andere Situationen, in denen ein Designer vorziehen kann, dass ein vgatherlink-Befehl fehlschlägt. Das Erlauben eines Fehlschlags kann potentiell die Anzahl von Konkurrenzsituationen reduzieren, während es die Effizienz verbessert. Namentlich kann ein Warten darauf, dass ein vgatherlink-Befehl für VLEN Adressen erfolgreich ist, die Konkurrenzsituationen erhöhen, während ein unmittelbares Ausgeben von vscattercond-Befehlen nur auf die Untermenge von erfolgreich verlinkten Adressen die Anzahl von Konkurrenzsituationen reduziert.
-
In der obigen Diskussion wird angenommen, dass alle Lock-Stellen eindeutig sind. Diese Beschränkung zwingt einen Programmierer dazu, die Locks in Untermengen von eindeutigen Locks vor einem Eintreten in die While-Schleife zu partitionieren, was eine potentiell teure Berechnung ist. Wenn z. B. VLEN Elemente gleichzeitig in einen Baum eingefügt werden, hätte der Programmierer keine Möglichkeit zur Compile-Zeit zu wissen, welche Elemente eindeutig sind.
-
Das Partitionieren von Locks in eindeutige Untermengen in Software ist teuer. Jedoch sind die Semantiken von vgatherlink- und vscattercond-Befehlen derart, dass ein Partitionieren nicht erforderlich ist. Diese Befehle unterscheiden sich von Scatter-Conditional- und gewöhnlichen Scatter-Operationen in ihrer Handhabung von Element-Aliasing, wobei eine einzelne SIMD-Operation versucht, mehrere Werte an dieselbe Stelle zu schreiben. Eines und nur eines der Aliasing-Elementaktualisierungen wird Erfolg haben, angezeigt durch die Ausgabemaske. In verschiedenen Ausführungsformen kann ein Hardware-Designer wählen, da sowohl Gather-Linked- als auch Scatter-Conditional-Befehle Ausgabemasken haben, die Aliasing-Detektion und -Resolution als Teil von einem der Befehle zu implementieren. Da vgahterlink- oder vscattercond-Befehle nur eine Untermenge von eindeutigen Adressen in Addr verarbeiten, garantiert dies, dass nur eindeutige Locks in einer gegebenen Iteration der While-Schleife erlangt werden, und der SIMD_update-Befehl wird nur auf den eindeutigen Elementen innerhalb der Gruppe von VLEN Elementen durchgeführt.
-
Während sich die obige Diskussion auf das Erlangen von Locks konzentriert, haben vgatherlink und vscattercond mindestens ein weiteres Verwendungsszenario: parallele Reduktionen. In zahlreichen Anwendungen führt der SIMD update-Befehl kein Zugreifen auf andere Objekte im gemeinsamen Speicher nach sich. Deshalb müssen solche Objekte nicht einen Lock erhalten haben, um Atomarität der Aktualisierung zu garantieren. Stattdessen können die vgatherlink- und vscattercond-Befehle auf den Daten, die aktualisiert werden, verwendet werden, wie aus Tabelle 2 folgt:
-
In diesem Code sammelt der vgatherlink-Befehl Datenelemente aus der globalen Datenstruktur (glb_data) in das Vektorregister V. Er setzt ebenfalls die Bits des Maskenregisters F auf 0, die den fehlgeschlagenen gesammelten Elementen entsprechen. Der SIMD update-Befehl aktualisiert das Vektorregister V. Dann streut der vscattercond-Befehl das Vektorregister V auf die globale Datenstruktur und setzt ebenfalls die Bits des Maskenregisters F auf 0, die den fehlgeschlagenen gestreuten Elementen entsprechen. Nach dem vscattercond-Befehl enthält das Maskenregister F eine 1 für jedes Element, das in dieser Iteration erfolgreich aktualisiert wurde. Eine Exklusiv-ODER (XOR)-Operation mit F 1 löscht diese Maskenbits und setzt die Bits in der Maske auf 1, die den Elementen entsprechen, die bisher nicht aktualisiert wurden.
-
Das direkte Anwenden der vgatherlink- und vscattercond-Befehle, um parallele Reduktionen durchzuführen, kann mehrere Vorteile mit sich bringen. Erstens ist der Code effizienter, da keine Notwendigkeit besteht, sich Locks zu greifen und sie freizugeben (d.h., der Code in Tabelle 2 ist wesentlich kürzer als der Code in Tabelle 1). Zweitens ist das Speicherverhalten besser, da keine Notwendigkeit besteht, für die Lock-Variablen auf den Speicher zuzugreifen.
-
Die hier beschriebenen Vektorbefehle können auf unterschiedliche Arten implementiert werden. Solche Befehle können verschiedene SIMD-Hardware-Ressourcen wirksam einsetzen, die eine Reservierungsstelle für jedes Element in den vgatherlink- und vscattercond-Operationen aufweisen. In einer Ausführungsform kann eine Granularität einer Reservierungsstelle pro 32-Bit-Element verwendet werden. Jedoch können andere Ausführungsformen eine kleinere oder größere Granularität haben. Die Anzahl von Elementen, die in einer einzelnen Iteration ein vgatherlink-Befehl sammelt und vscattercond streut kann ein Entwurfsparameter sein, da das Erlauben, dass eine größere Anzahl von Elementen gesammelt und gestreut wird, zwar eine bessere Leistungsfähigkeit bereitstellt, jedoch mehr Ressourcen erfordert.
-
In einer Ausführungsform können die vgatherlink- und vscattercond-Befehle das im Anhang I bzw. II gezeigte externe Verhalten aufweisen.
-
Ausführungsformen können somit eine effiziente Unterstützung für atomare Operationen in einer SIMD-Architektur bereitstellen. Auf diese Art und Weise kann die Notwendigkeit, atomare Zugriffe auf mehrere Speicherstellen zu serialisieren, unter Verwendung der hier beschriebenen Befehle vermieden werden, um einen Zugriff auf solche mehreren Stellen unter Verwendung einer effizienten Schleifenkonstruktion, z.B. einer Do-While-Schleife, zu ermöglichen.
-
Ausführungsformen der Befehle können in verschiedenen Anwendungen verwendet werden. Für die Verwendung von Locks können z. B. die beschriebenen Befehle verwendet werden, um Operationen in verschiedenen Anwendungen, wie z. B. Anwendungen für physikalische Simulation, durchzuführen. In ähnlicher Weise können die beschriebenen Befehle für Reduktionsoperationen in Verbindung mit verschiedenen Anwendungen verwendet werden, z. B. Bildverarbeitungsanwendungen und Anwendungen, die dünnbesetze Primitive der linearen Algebra verwenden. Selbstverständlich ist der Umfang der vorliegenden Erfindung in dieser Hinsicht nicht beschränkt und die hier beschriebenen Befehle können in anderen Anwendungen verwendet werden.
-
Nun Bezug nehmend auf 1A ist ein Blockdiagramm eines Prozessorkerns in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung gezeigt. Wie in 1A gezeigt, kann ein Prozessorkern 10 ein einzelner Kern eines Mehrfachkernprozessors sein, der eine Vielzahl von Kernen aufweist, die ähnlich zu dem des Kerns 10 konfiguriert sind. Wie in 1A gezeigt, kann der Kern 10 aus einer Architektur sein, die SIMD-Operationen unterstützt. Zum Beispiel können verschiedene Komponenten von Pipeline-/funktionalen Einheiten 20 erweitert werden, um Vektorunterstützung bereitzustellen, z. B. durch erweiterte Register und funktionale Einheiten, wie z. B. ALUs usw.
-
Weiterhin Bezug nehmend auf 1A können die Pipeline-/funktionalen Einheiten 20 mit einer Lade/Speichereinheit (LSU) 30 und einer Gather/Scatter-Einheit (GSU) 40 gekoppelt sein. Die LSU 30 kann die Ausführung von Lese- und Speicherbefehlen mit einem Cache-Speicher 50 handhaben, der in einer Ausführungsform ein Level-1 (L1)-Cache sein kann. Ähnlicherweise kann die GSU 40 die Ausführung von Gather- und Scatter-Befehlen handhaben, wie z. B. den hier beschriebenen Gather-Linked-Vektor- und Scatter-Conditional-Vektorbefehlen.
-
Während diese Einheiten auf unterschiedliche Art und Weise konfiguriert sein können, ist nun Bezug nehmend auf 1B eine beispielhafte Repräsentation einer Gather/Scatter-Einheit in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung gezeigt. Wie in 1B gezeigt, kann die GSU 40 eine Steuerlogik 42 aufweisen, die verschiedene Hardware, Firmware und Software oder Kombinationen davon aufweisen kann, um die Ausführung von verschiedenen Vektorbefehlen zu handhaben, wie z. B. den hier beschriebenen Befehlen. Um solche Operationen herbeizuführen, kann die Steuerlogik 42 in Kommunikation mit einem Maskenspeicher 44 sein, der eine oder mehrere Speicherstellen aufweisen kann, um Speicherung von Maskeninformationen, z. B. in der Form einer Vektormaske, bereitzustellen, die als Eingabe- und/oder Ausgabemasken für die unterschiedlichen hier beschriebenen Befehle verwendet werden können. Des Weiteren kann die Steuerlogik 42 in Kommunikation mit einem Vektorspeicher 46 stehen, der eine Vektorregisterdatei oder ein anderer temporärer Speicher sein kann, um Speicherung von Vektordatenelementen bereitzustellen, die als Operanden für die verschiedenen hier beschriebenen Befehle verwendet werden. Des Weiteren kann eine Mischlogik 48 bereitgestellt sein, um ein Mischen von verschiedenen Datenelementen gemäß Vektormischbefehlen, wie z. B. den hier beschriebenen, bereitzustellen, die von der Steuerlogik 42 implementiert sein können. Wie des Weiteren in 1B gezeigt ist, kann die Steuerlogik 42 wiederum mit Upstream-Abschnitten eines Kerns, z. B. den Pipeline-/funktionalen Einheiten 20 aus 1A, und einem Downstream-Abschnitt des Kerns kommunizieren, z. B. dem Cache-Speicher 50. Während sie in dieser bestimmten Implementierung in der Ausführungsform aus 1B gezeigt ist, sollte verständlich sein, dass der Umfang der vorliegenden Erfindung in dieser Hinsicht nicht beschränkt ist.
-
In einer Ausführungsform kann die GSU 40 eine Gather-Linked-Vektoroperation genauso handhaben, wie eine Gather-Operation, außer dass sie Load-Linked-Anfragen an den Speicher 50 erzeugt und sendet. Ähnlicherweise kann die GSU 40 Store-Conditional-Anfragen an den L1-Cache statt des normalen Speichers senden. Zusätzlich baut die GSU 40 die Ausgabemaske für diese Operationen basierend auf Erfolg oder Fehlschlag der individuellen Anfragen auf und speichert sie.
-
In einer Ausführungsform kann eine Cache-Tag-Struktur des Cache-Speichers 50 einen sogenannten Gather-Load-Control-Store (GLSC)-Eintrag pro Cache-Zeile aufweisen, um Gather-Linked- und Scatter-Conditional-Befehle zu unterstützen. Ein GLSC-Eintrag kann zwei Felder enthalten: ein Gültigkeitsbit und einen Hardware-Thread-Identifikator (ID) (um zwischen den gleichzeitigen Multithreaded (SMT)-Threads auf demselben Kern zu unterscheiden). Während die GSU 40 Load-Linked-Anfragen an den Cache-Speicher 50 sendet, können für Gahter-Linked-Operationen einige der Anfragen fehlschlagen, während andere Anfragen erfolgreich sein werden. Für jede Anfrage, die erfolgreich ist, aktualisiert der Cache den entsprechenden GLSC-Eintrag (z. B. wird das Gültigkeitsbit gesetzt und die Thread-ID des Anfragers wird gefüllt), die GSU 40 setzt das entsprechende Bit in der Ausgabemaske und die GSU 40 platziert die Daten in das Zielregister. Für Scatter-Conditional-Operationen sendet die GSU 40 einen Satz von Store-Conditional-Anfragen an den Cache-Speicher 40. Eine individuelle Store-Conditional-Anfrage ist erfolgreich, wenn das entsprechende Gültigkeitsbit des GLSC-Eintrags gesetzt ist und die Thread-ID des GLSC-Eintrags mit der Thread-ID des Anfragers übereinstimmt. In einer Ausführungsform wird dies wahr sein, wenn die entsprechende Cache-Zeile nicht durch einen eingreifenden Schreibvorgang modifiziert wurde oder hinausgeworfen wurde, da sie erfolgreich durch eine übereinstimmende Load-Linked-Anfrage von einer Gather-Linked-Operation verlinkt wurde. Wenn eine individuelle Store-Conditional-Anfrage erfolgreich ist, löscht der Cache das GLSC-Gültigkeitsflag, modifiziert die Daten in der Cache-Zeile und die GSU 40 setzt das entsprechende Bit in der Ausgabemaske.
-
Nun Bezug nehmend auf 2 ist ein Flussdiagramm zum Durchführen von atomaren Vektoroperationen in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung gezeigt. Wie in 2 gezeigt, kann ein Verfahren 100 Gather-Linked-Vektorbefehle und Scatter-Conditional-Vektorbefehle verwenden, um atomare Aktualisierungen von Vektordatenelementen zu ermöglichen. Beachte, dass obwohl sie mit dieser bestimmten Implementierung in der Ausführungsform aus 2 gezeigt ist, der Umfang der vorliegenden Erfindung in dieser Hinsicht nicht beschränkt ist. Wie in 2 gezeigt, kann das Verfahren 100 in Block 110 beginnen, wobei eine Vektormaske auf einen gültigen Zustand gesetzt werden kann und Vektorindexinformationen erhalten werden können. Solche Operationen können durchgeführt werden, um somit eine Eingabemaske auf einen gültigen Zustand zu setzen und um Indexindices für SIMD-Datenelemente zu berechnen (d.h., Adressen zu erhalten).
-
Die Steuerung gibt dann weiter zu Block 120 ab, wo eine Schleife initiiert werden kann, die iteriert wird, bis alle SIMD-Elemente aktualisiert worden sind. Diese Schleife kann mit einem Durchführen eines Gather-Linked-Vektorbefehls beginnen, um Vektor-Lock-Informationen zu erhalten. Insbesondere kann dieser Gather-Linked somit verwendet werden, um bis zu VLEN Lock-Werte zu erhalten. Falls er für ein gegebenes Datenelement nicht erfolgreich ist, wie bei Raute 125 bestimmt, die anzeigt, dass ein Lock für ein gegebenes Datenelement nicht verfügbar ist, gibt die Steuerung zu Block 130 ab, wo ein entsprechender Vektormaskenindikator für den nicht verfügbaren Lock auf einen ungültigen Zustand gesetzt werden kann. Falls stattdessen ein gegebener Lock verfügbar ist, kann ein Scatter-Conditional-Vektorbefehl ausgeführt werden, um zu versuchen, solche verfügbaren Datenelemente zu verriegeln (Block 140). Für beliebige erfolgreiche Operationen, die einen Lock erhalten, kann eine Ausgabemaske, die dem Scatter-Conditional-Vektorbefehl zugeordnet ist, gesetzt bleiben, während für einen beliebigen solcher Locks, die nicht in der Lagen waren, erhalten zu werden, die Maske stattdessen auf einen ungültigen Zustand gesetzt werden kann. Die Steuerung gibt dann zu Block 150 ab, wo eine SIMD-Aktualisierung auf einer Untermenge der Datenelemente durchgeführt werden kann. Insbesondere kann die SIMD-Aktualisierung für beliebige Datenelemente, für die der Lock bei Block 140 erhalten wurde, durchgeführt werden. Die Steuerung gibt dann zu Block 160 ab, wo ein Scatter-Vektorbefehl ausgeführt werden kann, um die aktualisierten Datenelemente zu entriegeln. Danach kann bei Raute 170 bestimmt werden, ob zusätzliche Vektordatenelemente verbleiben, um aktualisiert zu werden. Falls dem so ist, gibt die Steuerung zurück zum Block 120 ab. Sonst kann das Verfahren 100 enden. Während sie in dieser bestimmten Implementierung in der Ausführungsform aus 2 gezeigt ist, ist der Umfang der vorliegenden Erfindung in dieser Hinsicht nicht beschränkt.
-
Ausführungsformen können ferner verwendet werden, um Scatter-Reduktionen in einem SIMD-Modus zu ermöglichen. Die Ausführungsformen unterteilen konzeptuell eine Scatter-Reduktionsoperation in drei Operationen. Erstens, partitioniere ein erstes Array in Chunks einer Länge, die der SIMD-Breite gleicht. Dieses Array kann ein Array aus ganzzahligen oder Fliesskommawerten gegebener Längen sein, z. B. ein erstes Array, ein sogenanntes C-Array mit Werten der Länge N. Beachte, dass ein weiteres Array, auf das als ein sogenanntes B-Array Bezug genommen wird, ein ganzzahliges Index-Array der Länge N sein kann, dessen Elemente im Bereich [1... M] liegen und das die Abbildung von jedem Element des C-Arrays auf ein anderes Array, A, der Länge M definiert. Beachte, dass die Verteilung von Indices (d.h. der Inhalte des Arrays B) oft zufällig ist. Darüber hinaus können mehrere Einträge des B-Arrays denselben Wert haben, was verursachen kann, dass mehrere Werte des C-Arrays in dasselbe Element des A-Arrays reduziert werden sollen. Zweitens, führe eine lokale Reduktion innerhalb jedes Chunks durch (von dem angenommen wird, dass er in SIMD-Registem ist); am Ende von jeder dieser Operationen wird ein SIMD-Register Werte halten, die eindeutigen Elementen von A innerhalb des Chunks entsprechen (d.h., keine zwei Werte innerhalb des Registers müssen auf dasselbe Element des Arrays reduziert werden), und alle duplizierten Werte wurden in dieses eindeutige Element reduziert. Drittens, führe eine Gather-Update-Scatter-Speicheroperation für jeden Chunk durch, um die Reduktion des Chunks abzuschlie-ßen.
-
Ausführungsformen können noch einen weiteren Vektorbefehl bereitstellen, um beim Durchführen von SIMD-Reduktionen in Registern zu unterstützen. Insbesondere kann der Befehl verwendet werden, um die eindeutigen Eintragungen in einem ersten SIMD-Register zu finden, und eine Mischsteuerung für die duplizierten Eintragungen zu erzeugen. Nach solchen Operationen kann die Mischsteuerung verwendet werden, um ein zweites SIMD-Register aus dem ersten SIMD-Register derart zu produzieren, dass sich Paare von duplizierten Elementen in ihrem jeweiligen SIMD-Register in sich entsprechenden Stellen befinden. Ferner wird eine Akkumulation von diesen zwei Vektorregistern durchgeführt, um entsprechende duplizierte Elemente aus jedem Paar in ein Zielvektorregister zu „reduzieren“. Die gesamte Sequenz wird wiederholt bis die verbleibenden Elemente alle auf unterschiedliche Elemente von A abbilden. Diese Sequenz akkumuliert so viele Paare von duplizierten Elementen wie möglich in jeder Iteration, um die Anzahl von Iterationen zu minimieren. Alternative Ausführungsformen können lediglich eine Untermenge der Paare von Duplikaten akkumulieren, um die Implementierungskosten zu reduzieren.
-
Vor dem Start der obigen zweiten Operation können die Arrays B und C in verschiedene Chunks (wie in der ersten Operation) aufgeteilt werden. Die Chunks werden in zwei SIMD-Register geladen (wir werden diese Register einfachheitshalber Vb und Vc nennen). Die zweite Operation kombiniert Elemente aus Vc, die denselben Wert in den entsprechenden Elementen aus Vb haben. Um diese dritte Operation durchzuführen, kann eine Sequenz von Befehlen verwendet werden, um jedes Element aus Vb gegen andere Elemente in Vb seriell zu prüfen, um zu bestimmen, ob dort irgendeine Übereinstimmung vorliegt. Falls Übereinstimmungen gefunden werden, werden die entsprechenden Elemente in Vc reduziert. Die folgende Tabelle 3 ist der Pseudo-Code dieser zweiten Operation:
-
Diese serielle Implementierung weist jedoch eine Komplexität von O(N
2) auf. Entsprechend können Ausführungsformen der vorliegenden Erfindung einen Vektorbefehl bereitstellen, auf den hier als ein Shuffle-to-Reduce-Vektorbefehl, vshuf2reduce, Bezug genommen wird, um die Komplexität dieser Operation auf O(logN) zu reduzieren. Dieser Vshuf2reduce-Befehl nimmt eine Quelle Vb und eine Eingabemaske (die anzeigt, welche Elemente gültig sind) und erzeugt eine Mischsteuerung (in einem skalaren Register) und aktualisiert das Maskenregister. In einer Ausführungsform hat der Befehl das folgende Format:
Opcode | Ziel | Quelle | Maske | Beschreibung |
vshuf2reduce | Dst | Vb | F | Vergleicht Elemente in Vb (alle mit allen) und erzeugt baumförmig eine Mischsteuerung zum Kombinieren von Elementen, die denselben Wert in Vb haben |
-
Somit führt dieser vshuf2reduce-Befehl Alle-mit-Allen-Vergleiche von Elementen in Vb gegen andere Elemente in Vb, um eine Mischsteuerung für Vc zu erzeugen. Die Mischsteuerung wird als eine Eingabe für einen Mischbefehl verwendet, um in einer paarweisen Form Elemente in Vc mit anderen Elementen in Vc aufzureihen, die denselben Index-Wert in Vb haben. Zusätzlich wird die Maske F zurückgegeben, in der ein Element, das einem der zwei Eintragungen von jedem Paar entspricht, auf gültig gesetzt ist.
-
Die dritte obige Operation ist dazu bestimmt, die Ausgabe der zweiten Operation, Voutput, mit den aktuellen Inhalten von C zu kombinieren. Dies involviert ein Lesen der Elemente von C, die Voutput entsprechen, ein Akkumulieren dieser Elemente mit Voutput und dann ein Speichern der neu akkumulierten Werte zurück an ihre entsprechenden Stellen in C.
-
Die folgende Tabelle 4 ist ein Pseudo-Code eines Durchführens einer Scatter-Reduktion unter Verwendung dieses Befehls:
-
Der vshuf2reduce-Befehl erzeugt Mischsteuerungen für eine Baumreduktion. Das heißt, dass von der While-Schleife erwartet wird, dass sie innerhalb von O(log(VLEN))) Schritten im Worst-Case abschließt (wenn alle Elemente gleich sind und somit in ein einziges Element reduzieren), was die Leistungsfähigkeit der zweiten Operation der oben beschriebenen Scatter-Reduktionsoperation signifikant verbessert. Falls alle Elemente von Vc eindeutige Werte von Vb haben, kann die Schleife in einer einzigen Iteration abschließen.
-
In einer Ausführungsform kann der vshuf2reduce-Befehl basierend auf dem folgenden Pseudo-Code aus Tabelle 5 implementiert sein:
-
Der elementweise Alle-mit-Allen-Vergleich kann in Stufen implementiert sein und die Mischsteuerung kann in einer Ausführungsform durch Verwenden einer vorprogrammierten Lookup-Tabelle erzeugt werden.
-
Anhang III zeigt eine Verwendung dieses Befehls für die zweite Operation einer skalaren Reduktion.
-
Ausführungsformen können einen weiteren Befehl bereitstellen, um eine effiziente SIMD-Ausführung von Histogrammberechnungen zu ermöglichen durch effiziente Behandlung des Falls, in dem mehrere Indices in einem SIMD-Register gleich sind. Ein solcher Befehl kann die Populationsanzahl von eindeutigen ganzzahligen Werten in einem SIMD-Quellregister berechnen. Die Ausgaben sind ein SIMD-Register, das die Populationsanzahl der eindeutigen Elemente hält, und ein Maskenregister, das anzeigt, welche Elemente eindeutig sind. In einer Ausführungsform kann dieser Befehl, auf den als vitemcount Bezug genommen wird, das folgende Format haben:
Opcode | Ziel | Quelle | Maske | Beschreibung |
vitemcount | Vd | Vd | F | Identifiziert und zählt die identischen Elemente in Vektor Vs und speichert die Anzahl in Vd. Setzt die Schreibmaske F, die eindeutigen Elementen von Vs entspricht. |
-
Als ein Arbeitsbeispiel nehme einen initialen Zustand wie folgt an (wobei „-“ bedeutet, dass die Werte egal sind):
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vs: | 15 | 10 | 15 | 0 | 10 | 15 | 10 | 1 |
Vd: | - | - | - | - | - | - | - | - |
Fmask | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
-
Nach den vitemcount-Befehlen ist der Zustand wie folgt:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vs: | 15 | 10 | 15 | 0 | 10 | 15 | 10 | 1 |
Vd: | - | - | - | 1 | - | 2 | 3 | 1 |
Fmask | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
-
Die Populationsanzahl von jedem Element Vs[i] von Vs wird in Vd[i] gespeichert. Die eindeutigen Indices in Vs haben ihre entsprechende Schreibmaske in Fmask gesetzt.
-
Mit diesem vitemcount-Befehl kann eine SIMD-Histogrammberechnung wie in Tabelle 6 folgt, bereitgestellt werden:
-
Wie in Tabelle 6 gezeigt, führt diese Berechnung in vier Stufen aus. In der ersten Stufe werden das Quellregister Vs und die Maske F aus einer Vektorregisterdatei (VRF) bzw. einer Maskenregisterdatei (RF) gelesen. In der zweiten Stufe wird ein Alle-mit-Allen-Vergleich durchgeführt, um eindeutige Elemente in Vs zu identifizieren. Das Ergebnis der zweiten Stufe ist ein 4-Bit-Tag, das jedem Element Vs[i] von Vs zugeordnet ist, so dass eine Gruppe von zwei oder mehr identischen Elementen dasselbe Tag hat. Die dritte Pipeline-Stufe verwendet die 4-Bit-Tags, um die Zahl von Elementen in jeder Gruppe von identischen Elementen zu zählen. In der vierten und letzten Stufe werden der Anzahlvektor und die Maske in Vd bzw. F geschrieben. In einigen Implementierungen wird dieser Befehl parallele Histogrammberechnungen ermöglichen und kann eine Beschleunigung gegenüber einer seriellen Implementierung bereitstellen.
-
Ausführungsformen können in zahlreichen unterschiedlichen Systemtypen implementiert sein. Nun Bezug nehmend auf 3 ist ein Blockdiagramm eines Systems in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung gezeigt. Wie in 3 gezeigt, ist ein Multiprozessorsystem 500 ein Punkt-zu-Punkt-Interconnect-System und weist einen ersten Prozessor 570 und einen zweiten Prozessor 580 auf, die über einen Punkt-zu-Punkt-Interconnect 550 gekoppelt sind. Wie in 3 gezeigt, kann jeder der Prozessoren 570 und 580 ein Mehrfachkernprozessor sein, aufweisend erste und zweite Prozessorkerne (d.h. Prozessorkerne 574a und 574b und Prozessorkerne 584a und 584b). Jeder Prozessorkern kann eine Logik, wie z. B. in den 1A und 1B gezeigt, aufweisen, um die Ausführung von Einzelbefehl-Vektoroperationen in Übereinstimmung mit einer Ausführungsform der vorliegenden Erfindung zu ermöglichen. Auf diese Weise können atomare Vektoroperationen durchgeführt werden und verschiedener Code kann ausgeführt werden, um die hier beschriebenen Vektorbefehle wirksam einzusetzen.
-
Weiterhin Bezug nehmend auf 3 weist der erste Prozessor 570 ferner einen Speicher-Controller-Hub (MCH) 572 und Punkt-zu-Punkt (P-P)-Schnittstellen 576 und 578 auf. Ähnlicherweise weist der zweite Prozessor 580 einen MCH 582 und P-P-Schnittstellen 586 und 588 auf. Wie in 4 gezeigt, koppeln die MCHs 572 und 582 die Prozessoren an jeweilige Speicher, namentlich an einen Speicher 532 und einen Speicher 534, die Teile eines Hauptspeichers sein können (z.B. ein dynamischer Direktzugriffsspeicher (DRAM)), der an die jeweiligen Prozessoren lokal angeschlossen ist. Der erste Prozessor 570 und der zweite Prozessor 580 können an einen Chipsatz 590 über P-P-Interconnects 552 bzw. 554 gekoppelt sein. Wie in 3 gezeigt, weist der Chipsatz 590 P-P-Schnittstellen 594 und 598 auf.
-
Ferner weist der Chipsatz 590 eine Schnittstelle 592 auf, um den Chipsatz 590 mit einer Hochleistungsgrafik-Engine 538 zu koppeln. Der Chipsatz 590 kann wiederum an einen ersten Bus 516 über eine Schnittstelle 596 gekoppelt sein. Wie in 3 gezeigt, können verschiedene I/O-Vorrichtungen 514 an den ersten Bus 516 gekoppelt sein, zusammen mit einer Bus-Bridge 518, die den ersten Bus 516 an einen zweiten Bus 520 koppelt. Verschiedene Vorrichtungen können an den zweiten Bus 520 gekoppelt sein, aufweisend z. B. eine Tastatur/Maus 522, Kommunikationsvorrichtungen 526 und eine Datenspeichereinheit 528, wie z. B. ein Plattenlaufwerk oder andere Massenspeichervorrichtungen, die in einer Ausführungsform Code 530 aufweisen können. Ferner kann eine Audio-I/O 524 an den zweiten Bus 520 gekoppelt sein.
-
Ausführungsformen können als Code implementiert sein und können auf einem Speichermedium gespeichert sein, das darauf Befehle gespeichert hat, die verwendet werden können, um ein System zu programmieren, diese Befehle durchzuführen. Das Speichermedium kann aufweisen, ist jedoch nicht beschränkt auf einen beliebigen Typ von Platten, aufweisend Floppy-Disks, optische Platten, Compact Disk Read-Only Memories (CD-ROMs), Compact Disk Rewritables (CD-RWs) und magneto-optische Platten, Halbleitervorrichtungen, wie z. B. Nurlesespeicher (ROMs), Direktzugriffsspeicher (RAMs), wie z. B. dynamische Direktzugriffsspeicher (DRAMs), statische Direktzugriffsspeicher (SRAMs), löschbare programmierbare Nurlesespeicher (EPROMs), Flash-Speicher, elektrisch löschbare programmierbare Nurlesespeicher (EEPROMs), magnetische oder optische Karten oder ein beliebiger anderer Medientyp, der zum Speichern von elektronischen Befehlen geeignet ist.
-
Während die vorliegende Erfindung mit Bezug auf eine beschränkte Zahl von Ausführungsformen beschrieben worden ist, wird sich der Fachmann zahlreicher Modifikationen und Variationen hiervon bewusst sein. Es ist beabsichtigt, dass die angefügten Ansprüche alle solche Modifikationen und Variationen abdecken, die dem wahren Wesen der vorliegenden Erfindung entsprechen und in den Umfang der vorliegenden Erfindung fallen.
-
Anhang II
-
Der vscattercond sollte das folgende externe Verhalten haben.
-
Anhang III
-
Initialer Zustand („-“ bedeutet, dass die Werte egal sind), SC = Shuffle_Control ist ein skalarer Operand, der hier jedoch zur Vereinfachung des Verständnisses als ein Vektor repräsentiert wird.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 15,0 | 14,0 | 13,0 | 12,0 | 11,0 | 10,0 |
F: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
F1: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Vtmp: | - | - | - | - | - | - | - | - |
SC | Identität | Identität | Identität | Identität | Identität | Identität | Identität | Identität |
L1: vshuf2reduce SC,, Vb, F aktualisiert F und SC
7 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 15,0 | 14,0 | 13,0 | 12,0 | 11,0 | 10,0 |
F: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
F1: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Vtmp: | - | - | - | - | - | - | - | - |
SC | 7->5 | Identität | Identität | Identität | 3->1 | 2->0 | Identität | Identität |
-
Falls die initialen Werte von Vb alle eindeutig sind, werden an diesem Punkt die F-Masken weiterhin alle 1sen sein. Es wird effektiv gleich der F1-Maske sein und die While-Schleife (L4 bis L9) würde nicht ausgeführt werden und Operation 2 würde abschließen. In diesem Beispiel ist die F-Maske nicht gleich wie die F 1-Maske, da einige Elemente von Vb identisch sind. Somit werden wir die Schleife (L4 bis L9) ausführen L4: Vshuffle. aktualisiert Vtmp.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 15,0 | 14,0 | 13,0 | 12,0 | 11,0 | 10,0 |
F: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
F1: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Vtmp: | - | - | 17,0 | - | - | - | 13,0 | 12,0 |
SC | 7->5 | Identität | Identität | Identität | 3->1 | 2->0 | Identität | Identität |
L5: Vadd aktualisiert Vc.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 22,0 |
F: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
F1: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Vtmp: | - | - | 17,0 | - | - | - | 13,0 | 12,0 |
SC | 7->5 | Identität | Identität | Identität | 3->1 | 2->0 | Identität | Identität |
-
In der Schleife zwischen L4 und L9 werden die vshuf2reduce, vshuffle und vadd wiederholt aufgerufen, bis sich die Maske nicht mehr ändert. Dies bedeutet das Ende der Reduktionsoperation. L6: F1 = F aktualisiert F 1
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 22,0 |
F: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
F1: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
Vtmp: | - | - | 17,0 | - | - | - | 13,0 | 12,0 |
SC | 7->5 | Identität | Identität | Identität | 3->1 | 2->0 | Identität | Identität |
L7: vshuf2reduce SC, , Vb, F aktualisiert F und SC
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 22,0 |
F: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
F1: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
Vtmp: | - | - | 17,0 | - | - | - | 13,0 | 12,0 |
SC | - | Identität | 5->0 | Identität | - | - | Identität | Identität |
-
L9 schleift zurück zu L4. Da F und F1 weiterhin unterschiedlich sind, müssten wir die Schleife für eine weitere Iteration ausführen. L4: Vshuffle. aktualisiert Vtmp.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 22,0 |
F: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
F1: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
Vtmp: | - | - | - | - | - | - | - | 32,0 |
SC | - | Identität | 5->0 | Identität | - | - | Identität | Identität |
L5: Vadd aktualisiert Vc.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 54,0 |
F: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
F1: | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
Vtmp: | - | - | - | - | - | - | - | 32,0 |
SC | - | Identität | 5->0 | Identität | - | - | Identität | Identität |
L6: F1 = F aktualisiert F 1
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 22,0 |
F: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
F1: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
Vtmp: | - | - | - | - | - | - | - | 32,0 |
SC | - | Identität | 5->0 | Identität | - | - | Identität | Identität |
-
L7: vshuf2reduce SC, , Vb, F findet keine weiteren Elemente des Vb-Vektors, die gleich sind. Somit aktualisiert es weder F noch SC.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 22,0 |
F: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
F1: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
Vtmp: | - | - | 17,0 | - | - | - | 13,0 | 12,0 |
SC | - | Identität | - | Identität | - | - | Identität | Identität |
-
L9: Rückschleife zum Anfang der While-Schleife, um die Bedingungen zu testen. Diesmal sind F und F1 gleich und die Schleife wird verlassen. Die Endzustände der Variablen sind wie folgt:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Vb: | 15 | 13 | 15 | 0 | 10 | 15 | 10 | 15 |
Vc: | 17,0 | 16,0 | 32,0 | 14,0 | 13,0 | 12,0 | 24,0 | 54,0 |
F: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
F1: | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |