DE102021108963A1 - Sperrenfreier arbeitseinsatz thread scheduler - Google Patents

Sperrenfreier arbeitseinsatz thread scheduler Download PDF

Info

Publication number
DE102021108963A1
DE102021108963A1 DE102021108963.8A DE102021108963A DE102021108963A1 DE 102021108963 A1 DE102021108963 A1 DE 102021108963A1 DE 102021108963 A DE102021108963 A DE 102021108963A DE 102021108963 A1 DE102021108963 A1 DE 102021108963A1
Authority
DE
Germany
Prior art keywords
cpu
threads
poller
cpus
controller
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.)
Pending
Application number
DE102021108963.8A
Other languages
English (en)
Inventor
Matthew Gates
Joel E. Lilienkamp
Alex Veprinsky
Susan Agten
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 Enterprise Development LP
Original Assignee
Hewlett Packard Enterprise Development LP
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 Enterprise Development LP filed Critical Hewlett Packard Enterprise Development LP
Publication of DE102021108963A1 publication Critical patent/DE102021108963A1/de
Pending legal-status Critical Current

Links

Images

Classifications

    • 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/46Multiprogramming arrangements
    • G06F9/48Program initiating; Program switching, e.g. by interrupt
    • G06F9/4806Task transfer initiation or dispatching
    • G06F9/4843Task transfer initiation or dispatching by program, e.g. task dispatcher, supervisor, operating system
    • G06F9/4881Scheduling strategies for dispatcher, e.g. round robin, multi-level priority queues
    • 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/46Multiprogramming arrangements
    • G06F9/50Allocation of resources, e.g. of the central processing unit [CPU]
    • G06F9/5005Allocation of resources, e.g. of the central processing unit [CPU] to service a request
    • G06F9/5027Allocation of resources, e.g. of the central processing unit [CPU] to service a request the resource being a machine, e.g. CPUs, Servers, Terminals
    • 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/46Multiprogramming arrangements
    • G06F9/54Interprogram communication
    • G06F9/544Buffers; Shared memory; Pipes
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F12/00Accessing, addressing or allocating within memory systems or architectures
    • G06F12/02Addressing or allocation; Relocation
    • G06F12/08Addressing or allocation; Relocation in hierarchically structured memory systems, e.g. virtual memory systems
    • G06F12/0802Addressing of a memory level in which the access to the desired data or data block requires associative addressing means, e.g. caches
    • G06F12/0806Multiuser, multiprocessor or multiprocessing cache systems
    • G06F12/0811Multiuser, multiprocessor or multiprocessing cache systems with multilevel cache hierarchies
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F12/00Accessing, addressing or allocating within memory systems or architectures
    • G06F12/02Addressing or allocation; Relocation
    • G06F12/08Addressing or allocation; Relocation in hierarchically structured memory systems, e.g. virtual memory systems
    • G06F12/0802Addressing of a memory level in which the access to the desired data or data block requires associative addressing means, e.g. caches
    • G06F12/0806Multiuser, multiprocessor or multiprocessing cache systems
    • G06F12/0815Cache consistency protocols
    • G06F12/0817Cache consistency protocols using directory methods
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2212/00Indexing scheme relating to accessing, addressing or allocation within memory systems or architectures
    • G06F2212/10Providing a specific technical effect
    • G06F2212/1016Performance improvement
    • G06F2212/1024Latency reduction
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2212/00Indexing scheme relating to accessing, addressing or allocation within memory systems or architectures
    • G06F2212/25Using a specific main memory architecture
    • G06F2212/254Distributed memory
    • G06F2212/2542Non-uniform memory access [NUMA] architecture

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Memory System Of A Hierarchy Structure (AREA)
  • Multi Processors (AREA)

Abstract

Es werden Systeme und Verfahren für sperrfreie Thread-Planung bereitgestellt. Threads können in einem Ringpuffer platziert werden, der von allen Computerverarbeitungseinheiten (CPUs), z. B. in einem Knoten, gemeinsam genutzt wird. Ein Thread, der einer CPU zugewiesen ist, kann in der lokalen Laufwarteschlange der CPU platziert werden. Wenn jedoch die lokale Warteschlange einer CPU geleert wird, prüft diese CPU den gemeinsam genutzten Ringpuffer, um festzustellen, ob irgendwelche Threads auf dieser CPU darauf warten, ausgeführt zu werden, und wenn dies der Fall ist, zieht die CPU einen Stapel von Threads, die sich auf diesen ausführungsbereiten Thread beziehen, um ihn auszuführen. Ist dies nicht der Fall, wählt eine inaktive CPU zufällig eine andere CPU aus, von der sie Threads abruft, und die inaktive CPU versucht, einen mit der CPU verknüpften Thread-Stapel aus dem gemeinsamen Ringpuffer abzurufen. Das Polling kann durch die Verwendung eines gemeinsamen Poller-Arrays gehandhabt werden, um das Polling dynamisch auf mehrere CPUs zu verteilen.

Description

  • Beschreibung des Standes der Technik
  • Das Aufkommen der Technologie hat zu einem exponentiellen Wachstum der Rechenleistung von Rechensystemen geführt. Die Verwendung von Multi-Prozessor-Geräten (z. B. Multi-Computer Processing Unit oder CPU) und Multi-Core-Prozessoren (die eine Anzahl von Kernen oder Prozessoren enthalten) in Rechensystemen hat ebenfalls zur Steigerung der Rechenleistung von Rechensystemen beigetragen. Jeder der Kerne oder Prozessoren kann einen unabhängigen Cache-Speicher enthalten.
  • Figurenliste
  • Die vorliegende Offenbarung wird gemäß einer oder mehrerer verschiedener Ausführungsformen unter Bezugnahme auf die folgenden Figuren detailliert beschrieben. Die Figuren dienen nur der Veranschaulichung und stellen lediglich typische oder beispielhafte Ausführungsformen dar.
    • zeigt ein Beispiel für ein Hardware-Computersystem, in dem verschiedene Ausführungsformen implementiert werden können.
    • veranschaulicht eine beispielhafte Eins-zu-vielen-Kern-Verarbeitungssystemarchitektur eines Prozessors im Hardware-Rechnersystem von .
    • zeigt einen Beispiel-Workflow für die Thread-Planung in Übereinstimmung mit verschiedenen Ausführungsformen.
    • zeigt einen beispielhaften Abfrage-Workflow in Übereinstimmung mit verschiedenen Ausführungsformen.
    • zeigt eine Beispiel-Computerkomponente, die in der Lage ist, Befehle zur Durchführung der Thread-Planung gemäß verschiedenen Ausführungsformen auszuführen.
    • zeigt eine Beispiel-Computerkomponente, die in der Lage ist, Befehle zur Durchführung von Abfragen in Übereinstimmung mit verschiedenen Ausführungsformen auszuführen.
    • zeigt eine Beispiel-Computerkomponente, mit der verschiedene hier beschriebene Merkmale und/oder Funktionen implementiert werden können.
  • Die Abbildungen erheben keinen Anspruch auf Vollständigkeit und beschränken die vorliegende Offenbarung nicht auf die genaue dargestellte Form.
  • Detaillierte Beschreibung
  • Prozessoren oder CPUs beziehen sich auf elektronische Schaltkreise innerhalb eines Computers, die die Anweisungen eines Computerprogramms ausführen, indem sie die grundlegenden arithmetischen, logischen, Steuer- und Ein-/Ausgabeoperationen (E/A) durchführen, die durch die Anweisungen spezifiziert werden. Die Verarbeitungsleistung von Computern kann durch die Verwendung von Multi-Core-Prozessoren oder CPUs gesteigert werden, was im Wesentlichen darauf hinausläuft, dass zwei oder mehr Einzelprozessoren (in diesem Sinne Kerne genannt) in einen integrierten Schaltkreis eingesteckt werden. Im Idealfall wäre ein Dual-Core-Prozessor fast doppelt so leistungsfähig wie ein Single-Core-Prozessor, obwohl in der Praxis der tatsächliche Leistungsgewinn geringer sein kann. Die Erhöhung der Anzahl der Kerne in einem Prozessor (d. h. Dual-Core, Quad-Core usw.) erhöht die Arbeitslast, die parallel verarbeitet werden kann. Dies bedeutet, dass der Prozessor nun zahlreiche asynchrone Ereignisse, Interrupts usw. verarbeiten kann. Bei Multiprozessor-Rechnern oder - Systemen können jedoch mehr als ein einzelner Prozessor oder eine CPU unterstützt werden, z. B. zwei bis acht oder noch viel mehr CPUs, wie es bei Petascale-Supercomputern und Exascale-Supercomputing-Systemen der Fall sein kann.
  • Im Allgemeinen umfasst der Speicher eines Computersystems einen Hauptspeicher, z. B. einen nichtflüchtigen Speicher (NVM), und einen Cache-Speicher (oder einfach Cache). Der Hauptspeicher kann ein physisches Gerät sein, das zum Speichern von Anwendungsprogrammen oder Daten im Rechensystem verwendet wird. Der Cache speichert Daten, auf die häufig zugegriffen wird, so dass keine Zeit für den Zugriff auf die Daten aus dem Hauptspeicher aufgewendet werden muss. Typischerweise werden die Daten zwischen dem Hauptspeicher und dem Cache in Blöcken fester Größe übertragen, die als Cache-Zeilen bezeichnet werden. Wenn ein Prozessor des Computersystems von einerStelle im Hauptspeicher lesen oder an diese schreiben muss, liest der Prozessor aus dem Cache oder schreibt in den Cache, wenn die Daten bereits im Cache vorhanden sind, was schneller ist als das Lesen aus dem oder Schreiben in den Hauptspeicher. Daten, die in den Cache geschrieben werden, werden im Allgemeinen in den Hauptspeicher zurückgeschrieben.
  • In einem Multi-Compute-Engine-System kann jede Compute-Engine, z. B. ein Kern oder ein Prozessor, mehrere Threads haben und einen oder mehrere Caches enthalten, und im Allgemeinen ist ein Cache als Hierarchie mit einer oder mehreren Cache-Ebenen organisiert. In konventionellen Multi-Compute-Engine-Systemen laufen Threads typischerweise so lange, bis der Thread aufgibt, schläft oder beendet wird, wobei jeder logische Thread einer CPU zu dem Zeitpunkt zugewiesen werden kann, zu dem der logische Thread erstellt wurde. Aufeinanderfolgende CPUs werden, z. B. in einem Round-Robin-Verfahren, für die Zuweisung zu einem logischen Thread ausgewählt, und nur die zugewiesene CPU kann den Thread ausführen. Bei einem solchen Scheduling-Mechanismus fehlt jedoch eine Möglichkeit, die Arbeit auf mehrere CPUs zu verteilen, und einige CPUs können gesättigt werden, während andere praktisch untätig bleiben. Die gesättigten CPUs können zu einem Engpass werden, was zu einer geringeren E/A-Leistung führt, die erreicht werden könnte, wenn die gleiche Arbeitsmenge auf mehr CPUs verteilt würde. Außerdem kann es zu Leistungsschwankungen zwischen Boot-Zyklen oder zwischen Array-Knoten kommen, da die Round-Robin-CPU-Zuweisung bei jedem Booten eines Knotens variieren kann.
  • Dementsprechend sind verschiedene Ausführungsformen auf ein Thread-Scheduling gerichtet, das sperrfrei ist und es ermöglicht, dass Threads zur Laufzeit dynamisch von verschiedenen CPUS ausgeführt werden. In einigen Ausführungsformen kann ein Scheduler einem bestimmten Scheduling-Algorithmus folgen, bei dem Folgendes durchgeführt wird: (1) Threads werden lokalen CPU-Laufwarteschlangen zugewiesen; (2) Threads werden in einem von allen CPUs gemeinsam genutzten Ringpuffer platziert, wenn die Threads laufbereit sind; (3) wenn die lokale Laufwarteschlange einer CPU geleert wird, prüft diese CPU den gemeinsam genutzten Ringpuffer, um festzustellen, ob irgendwelche Threads darauf warten, auf dieser CPU zu laufen, und wenn dies der Fall ist, zieht die CPU einen Stapel von Threads, die mit diesem laufbereiten Thread zusammenhängen, und platziert die Threads in ihrer lokalen Laufwarteschlange; (4) wenn nicht, wählt eine Idle-CPU zufällig eine andere CPU zum Stehlen von Threads aus (vorzugsweise eine näher gelegene CPU), und die Idle-CPU versucht, einen mit der CPU verbundenen Thread-Stapel aus dem gemeinsamen Ringpuffer auszulagern - dies kann wiederholt werden, wenn eine ausgewählte CPU keine zugehörigen Threads im gemeinsamen Ringpuffer hat; (5) die Idle-CPU führt den von der anderen CPU gestohlenen Thread-Stapel in ihrer lokalen Ausführungswarteschlange in Prioritätsreihenfolge aus; (6) der Prozess wiederholt sich für jede Idle-CPU. Wie weiter unten beschrieben wird, kann ein Scheduler in ausführbarer Software implementiert werden, z. B. auf Knotenebene.
  • zeigt ein Beispiel für ein Hardware-Computersystem 1 mit Multi-Core-Prozessoren oder CPUs, deren Verarbeitungs-Threads gemäß verschiedenen Ausführungsformen ausgeglichen sein können. Ein System, wie das Hardware-Computersystem 1, kann verschiedene Elemente oder Komponenten, Schaltungen, darauf gespeicherte und ausführbare Software usw. umfassen. Der Einfachheit halber und zur leichteren Erklärung werden jedoch nur einige Aspekte dargestellt und beschrieben.
  • Das Hardware-Computersystem 1 kann ein Betriebssystem oder OS 2 enthalten, in dem ein oder mehrere Prozesse, die null oder mehr Threads enthalten, auf mehreren CPUs (10 und 30) laufen (oder im Leerlauf sind) . Wie hierin beschrieben, kann ein Prozess die Fähigkeit haben, einen Thread zu erzeugen, der wiederum einen anderen „leichtgewichtigen“ Prozess erzeugt, der die Daten des „übergeordneten“ Prozesses mitbenutzt, der aber unabhängig auf einem anderen Prozessor zur gleichen Zeit wie der übergeordnete Prozess ausgeführt werden kann. Zum Beispiel kann ein Prozess N 4 (zusammen mit anderen Prozessen) im Betriebssystem 2 im Leerlauf sein, während andere Prozesse, z. B. die Prozesse 12, 32, auf den CPUs 10 bzw. 30 laufen. veranschaulicht ferner einen High-Level-Fluss für Speicherabbildungen jedes ausführenden Prozesses, der die virtuelle Speicherabbildung 40 für CPU 10 und die virtuelle Speicherabbildung 42 für CPU 30 sowie die physische Speicherabbildung 50 umfasst.
  • zeigt eine Beispielarchitektur der CPU 10 aus . In einem Beispiel kann die CPU 10 mit einem verzeichnisbasierten Protokoll betrieben werden, um Cache-Kohärenz zu erreichen. CPU 10 kann z. B. ein Multiprozessorsystem, ein System mit einem oder mehreren Kernen oder ein System mit mehreren Kernen sein. Dementsprechend kann die CPU 10 mehrere Prozessoren oder Kerne umfassen und in diesem Beispiel mehrere Kerne 10A, 10B, . ..10N.
  • Jeder der Kerne 10A, 10B, ... 10N, kann eine oder mehrere Cache-Ebenen 14A, 14B, ... 14N zugeordnet sein. Ein Netzwerk 16 (das ein Systembus sein kann) ermöglicht es den Kernen 10A, 10B, ... 10N sowohl untereinander als auch mit einem Hauptspeicher 18 der CPU 10 kommunizieren. Die Daten des Hauptspeichers 10 können von jedem Kern der CPU 10 zwischengespeichert werden, z. B. von jedem der Kerne 10A, 10B ...10N.
  • Zurückkommend auf implementieren die CPUs 10, 30 jeweils ein virtuelles Speicherverwaltungssystem. Beispielsweise erzeugt die CPU 10 Speicherreferenzen, indem sie zunächst eine virtuelle Adresse bildet, die die Adresse innerhalb eines gesamten Adressbereichs durch die architektonischen Spezifikationen des Computers oder den vom Betriebssystem 2 erlaubten Teil davon darstellt. Die virtuelle Adresse kann dann in eine physikalische Adresse in der physikalischen Speicherabbildung 50 übersetzt werden, die durch die Größe des Hauptspeichers eingeschränkt ist. In einigen Ausführungsformen erfolgt die Übersetzung mit Seiten, so dass eine virtuelle Seitenadresse für eine Seite in der virtuellen Speicherabbildung 40 in eine physische Adresse für eine Seite in der physischen Speicherabbildung 50 übersetzt wird. Eine Seitentabelle wird im Speicher verwaltet, um die Übersetzung zwischen virtueller Adresse und physikalischer Adresse bereitzustellen, und in der Regel ist ein Übersetzungspuffer (nicht dargestellt) in der CPU enthalten, um die zuletzt verwendeten Übersetzungen zu halten, so dass ein Verweis auf eine Tabelle im Speicher 18 nicht erfolgen muss, um die Übersetzung zu erhalten, bevor ein Datenverweis erfolgen kann.
  • Wie oben angedeutet, sind verschiedene Ausführungsformen auf Work-Stealing ausgerichtet, um zu ermöglichen, dass Threads, z. B. Threads, zur Laufzeit dynamisch von verschiedenen CPUs ausgeführt werden. Auf diese Weise wird die Arbeit auf die verfügbaren CPUs verteilt, ohne dass eine bestimmte CPU überlastet wird und/oder ein Engpass bei der Verarbeitung entsteht/entstehen. In einigen Ausführungsformen verkörpert der Work-Stealing-Algorithmus, nach dem ein lokaler CPU-Scheduler arbeitet (z. B. Scheduler 314 ( )), einen sperrfreien Ansatz. Sperren kann sich auf einen Mechanismus beziehen, durch den eine Serialisierungsressource Daten vor dem Zugriff durch viele Threads schützt. Das heißt, typischerweise kann ein Kern ein Spin-Lock erwerben, damit der Zugriff auf Datenstrukturen synchronisiert werden kann und um Verarbeitungskonflikte zwischen eingehenden/ausgehenden Paketen zu vermeiden. Das Sperren kann jedoch zu vergeudeten CPU-Zyklen/Spinning führen, während auf das Erwerben einer Sperre gewartet wird. Insbesondere bei modernen Systemen mit mehr als z. B. 100 Kernen pro System würde ein konventionelles Thread-Scheduling eine (Hardware-)Skalierung stark behindern und/oder zu hohen Latenzzeiten führen.
  • zeigt einen beispielhaften Arbeitsablauf zur Implementierung eines sperrfreien Work-Stealing-Ansatzes zur Planung von Threads gemäß einer Ausführungsform. Eine lokale CPU 200 ist in dargestellt, wobei die lokale CPU 200 eine lokale Laufwarteschlange 205 mit Threads 210, 212, 214 haben kann, die von der lokalen CPU 200 ausgeführt werden sollen. Wie oben erwähnt, kann eine CPU einen oder mehrere Kerne haben. In jedem CPU-Kern können Threads zur Verarbeitung von Anfragen erstellt werden. Pro CPU-Kern kann ein Thread erstellt werden, es sind aber auch mehrere Threads möglich. Threads laufen typischerweise so lange weiter, wie es Arbeit gibt, d. h. eine Anfrage bearbeitet werden muss. Ein Thread kann sich auf eine Grundeinheit der CPU-Nutzung beziehen und kann einen Programmzähler, einen Stack und einen Satz von Registern umfassen. Threads laufen im gleichen Speicherkontext und können während der Ausführung die gleichen Daten gemeinsam nutzen. Ein Thread ist das, was eine CPU tatsächlich ausführen darf, und der Zugriff auf gemeinsam genutzte Ressourcen, z. B. die CPU, wird entsprechend geplant. Im Gegensatz dazu beinhaltet oder initiiert ein Prozess ein Programm, und ein Prozess kann einen oder mehrere Threads umfassen/umfassen (der Thread ist eine Ausführungseinheit im Prozess). Und während Threads Adressräume des Prozesses verwenden, werden beim Wechsel einer CPU von einem Prozess zu einem anderen die aktuellen Informationen in einem Prozessdeskriptor gespeichert und die Informationen des neuen Prozesses geladen.
  • Wie in dargestellt, kann ein gemeinsam genutzter Ringpuffer implementiert und für jede CPU zugänglich gemacht werden. Das heißt, in einigen Ausführungsformen kann jede CPU, wie z. B. CPU 200, darin implementiert sein oder Zugriff auf einen Cache oder eine Warteschlange von Threads haben, die von der CPU ausgeführt werden sollen. Im Gegensatz zu herkömmlichen Systemen, bei denen Threads einer bestimmten CPU zugewiesen werden können, werden Threads in einem gemeinsam genutzten Ringpuffer, z. B. dem gemeinsam genutzten Ringpuffer 215, in eine Warteschlange gestellt. Es ist zu beachten, dass jede geeignete Datenstruktur oder jeder geeignete Mechanismus verwendet werden kann, um anstehende Threads, die von der CPU 200 ausgeführt werden sollen, in eine Warteschlange zu stellen. Der gemeinsam genutzte Ringpuffer ist lediglich eine Art der Implementierung einer solchen Thread-Warteschlange. Andere Datenstrukturen oder Speichermechanismen können verwendet werden, um Threads in Übereinstimmung mit anderen Ausführungsformen in eine Warteschlange zu stellen.
  • Es versteht sich, dass der gemeinsam genutzte Ringpuffer 215 im physischen/Hauptspeicher (z. B. im Speicher 18 von implementiert sein kann, auf den jede CPU in einem System zugreifen kann. In einigen Ausführungsformen kann der gemeinsam genutzte Ringpuffer 215 lokal in Software implementiert sein, z. B. als Puffer, auf den lokale CPUs zugreifen können. Es sei ferner darauf hingewiesen, dass die Datenkohärenz in der Hardware aufrechterhalten werden kann, d. h., der Algorithmus zum Stehlen von Arbeit muss die Datenkohärenz nicht berücksichtigen. Beispielsweise kann ein Knoten-Controller, der einen Knoten steuert, zu dem eine CPU gehören kann, einen Kohärenz-Verzeichnis-Cache unterhalten, um die Datenkohärenz zwischen Hauptspeicher und lokalem Speicher zu gewährleisten, und die atomaren Anweisungen, die zur Implementierung des Work-Stealing-Algorithmus verwendet werden, wirken bereits auf den gemeinsamen Speicher. Dementsprechend werden keine Sperren verwendet oder benötigt.
  • Im Betrieb kann die lokale CPU 200 alle aufgeweckten Threads in ihren gemeinsamen Ringpuffer, in diesem Fall in den gemeinsamen Ringpuffer 215, legen. Threads können durch eine Fork- oder ähnliche Funktion(en) in einem Computerprogramm erzeugt werden. In anderen Fällen können Threads z. B. durch einen Cron-Job aufgeweckt werden, bei dem der Thread nach einem bestimmten Timer/nach Ablauf einer bestimmten Zeitspanne aufgeweckt wird. Nach dem Aufwecken können Threads von der lokalen CPU 200 in den gemeinsamen Ringpuffer 215 gelegt werden. Wie in dargestellt, befinden sich die Threads 220-228 derzeit im gemeinsamen Ringpuffer 215. Zu diesem Zeitpunkt sind die Threads 220-228 noch keiner bestimmten CPU zugewiesen.
  • Es sollte beachtet werden, dass jeder Thread einen erlaubten Satz von CPUs haben kann, auf denen er laufen kann, und dieser erlaubte Satz kann programmierbar sein und bestimmt werden, z. B. von einem Entwickler, der den Thread erstellt und seine Attribute definiert. Beispielsweise kann ein Thread so eingestellt werden, dass er auf einem bestimmten Knoten erstellt wird. In diesem Fall kann eine bestimmte NUMA-Affinität (Non-Uniform Memory Access) für eine bestimmte CPU/Speicher eingestellt werden. Zum Beispiel kann ein Thread für die Erstellung auf einer bestimmten CPU (CPU-Affinität) eingestellt werden. Ein Thread kann z. B. keine Affinität haben, in diesem Fall kann jede CPU den Thread ausführen. Es sollte verstanden werden, dass sich NUMA auf ein Speicherdesign bezieht, dessen Architektur eine Vielzahl von Knoten umfassen kann, die über ein symmetrisches Multiprocessing (SMP)-System miteinander verbunden sind. Jeder Knoten selbst kann ein kleiner SMP sein, der mehrere Prozessorsockel mit Prozessoren/CPUs und zugehörigem Speicher umfasst, die untereinander verbunden sind, wobei der Speicher innerhalb des Knotens von allen CPUs gemeinsam genutzt wird. Der Speicher innerhalb eines Knotens kann als lokaler Speicher für die CPUS des Knotens betrachtet werden, während der Speicher anderer Knoten als entfernter Speicher betrachtet werden kann. Knoten-Controller innerhalb jedes Knotens ermöglichen den CPUs den Zugriff auf entfernten Speicher innerhalb des Systems. Ein Knoten-Controller kann als erweiterter Speicher-Controller betrachtet werden, der den Zugriff auf einen Teil oder den gesamten lokalen Speicher und den Zugriff der CPUs des Knotens auf den entfernten Speicher verwaltet. Ein Scheduler gemäß verschiedenen Ausführungsformen kann in Software implementiert sein, die auf dem Knoten ausgeführt wird, z. B. in einem Knoten-Controller.
  • Nehmen wir den Fall eines Threads mit einer bestimmten CPU-Affinität als Beispiel: Wenn der Thread aufgeweckt wird (wie oben beschrieben), wird der Thread der CPU zugeordnet, an die der aufgeweckte Thread gebunden ist (aufgrund der angegebenen Affinität). Wie oben erwähnt, ist die CPU, in diesem Fall die lokale CPU 200, zufällig die CPU, auf der der Thread ausgeführt werden soll. Daher platziert die CPU 200 den Thread im gemeinsamen Ringpuffer 215.
  • Um einen oder mehrere Threads auszuführen, die derzeit im gemeinsam genutzten Ringpuffer 215 in der Warteschlange stehen, kann die lokale CPU 200 Threads in Stapeln oder einzeln dequeuen (obwohl das Dequeuen in Stapeln effizienter sein kann). Das heißt, jede Dequeue-Operation auf dem gemeinsamen Ringpuffer 215 kann eine gewisse Latenz (Speicher-Overhead) haben, und die Verarbeitung von Thread-Stapeln amortisiert diese Latenz/Verzögerung, indem mehrere Elemente in einer einzigen Dequeue-Operation abgerufen werden. Es sollte klar sein, dass ein Stapel eine beliebige Zahl zwischen eins und einer Größe des gemeinsam genutzten Ringpuffers sein kann, obwohl eine standardmäßige maximale Thread-Stapelgröße gewählt werden kann, z. B. auf der Grundlage von Tests und der Abstimmung des Algorithmus, nach dem die Ausführungsformen arbeiten. Es sei darauf hingewiesen, dass die Implementierung eines gemeinsam genutzten Ringpuffers, z. B. des gemeinsam genutzten Ringpuffers 215, eine Schnittstelle bereitstellt, über die bis zu N Elemente (Threads) in einem einzigen Aufruf aus der Warteschlange entfernt und in einem Rückgabepuffer zur Verarbeitung durch den Aufrufer abgelegt werden können. Nach der Entnahme eines Stapels von Threads aus dem gemeinsamen Ringpuffer 215 können die entnommenen Threads in die lokale Laufwarteschlange 205 gestellt werden. Abhängig von der angegebenen Affinität, z. B. zu einer bestimmten CPU oder einem bestimmten Knoten oder Prozessorsockel (im Fall von NUMA-Affinität), kann nur eine bestimmte CPU/ein bestimmter Satz von CPUs in der Lage sein, einen Stapel von Threads aus der Warteschlange zu nehmen. Im Fall eines Threads ohne Affinität kann jede CPU den Thread aus der Warteschlange nehmen.
  • Wenn sich Threads in der lokalen Ausführungswarteschlange 205 befinden, kann die lokale CPU 200 diese Threads ausführen, in diesem Beispiel die Threads 210-214. In einigen Ausführungsformen kann die lokale CPU 200 die Threads 210-214 in einer Prioritätsreihenfolge ausführen, dies ist jedoch nicht unbedingt erforderlich, und die Threads können in einer anderen Reihenfolge oder in beliebiger Reihenfolge ausgeführt werden. Das heißt, die lokale CPU 200 kann einen Thread, z. B. den Thread 210, ausführen. Wenn ein Thread zu einem aktuellen Kontext zurückkehrt, kann die lokale CPU 200 einen anderen Thread ausführen, der in diesem Fall Thread 212, 214 usw. sein kann.
  • Wenn CPUs im Leerlauf sind, d. h. keine Threads auszuführen haben, wie z. B. die Idle-CPU 230, kann sie Arbeit oder einen Stapel Threads aus dem gemeinsamen Ringpuffer 215 „stehlen“. Leerlauf-CPUs, wie z. B. die Leerlauf-CPU 230, können einen Stapel von Threads aus dem gemeinsamen Ringpuffer stehlen, wenn dem Stapel von Threads keine Affinität zugeordnet ist, die die Leerlauf-CPU 230 daran hindern würde, diesen Stapel von Threads auszuführen. Zum Beispiel kann die Idle-CPU 230 in einen Satz von CPU/NUMA-Affinitäten fallen. Wenn die Idle-CPU 230 einen Stapel von Threads nicht ausführen kann, verbleiben diese Threads im gemeinsamen Ringpuffer 215. Es ist zu beachten, dass alle Threads unabhängig von der Affinität an den gemeinsamen Ringpuffer 215 gesendet werden können, da der gemeinsame Ringpuffer 215, in den die Threads gesendet werden, der Affinität eines Threads entspricht. Das heißt, dass für jeden gemeinsam genutzten Ringpuffer nur CPUs, die in der Lage sind, Threads (auch als Tasks bezeichnet) mit einer dem gemeinsam genutzten Ringpuffer entsprechenden Affinität auszuführen, versuchen werden, Threads daraus zu stehlen. Nach dem Stehlen eines Stapels von Threads, ähnlich dem Vorgang der lokalen CPU 200, entnimmt die Idle-CPU 230 den Stapel von Threads aus dem gemeinsamen Ringpuffer 215. Die Idle-CPU 230 kann den entnommenen Stapel von Threads zur Ausführung in ihre eigene lokale Warteschlange (nicht dargestellt) stellen, und die (nicht mehr inaktive) CPU 230 kann die Threads ausführen.
  • Wie oben erwähnt, kann jede CPU mindestens einen gemeinsam genutzten Ringpuffer haben, den eine Idle-CPU stehlen kann, sofern keine Affinität besteht, die eine Idle-CPU daran hindert, einen Stapel von Threads auszuführen. Eine Idle-CPU kann lokal zu der CPU sein, aus deren gemeinsamem Ringpuffer die Idle-CPU stehlen kann, oder die Idle-CPU kann entfernt von der CPU sein, aus deren gemeinsamem Ringpuffer die Idle-CPU stehlen kann, abhängig von der Architektur des Systems, zu dem die CPUs gehören. Zum Beispiel kann ein System, wie oben angedeutet, eine Vielzahl von Knoten haben, die miteinander verbunden sind, wobei jeder der Knoten eine oder mehrere CPUs umfasst.
  • Wenn eine CPU im Leerlauf versucht, Arbeit (Threads) von einer anderen CPU zu stehlen, kann die CPU im Leerlauf eine andere CPU im System zufällig auswählen, von der sie versuchen kann, Arbeit zu stehlen. In einigen Ausführungsformen kann ein Hyperthread- und NUMA-fähiger Auswahlalgorithmus verwendet werden. In einigen Ausführungsformen „bevorzugt“ ein solcher Algorithmus das Stehlen von CPUs, die in Bezug auf die CPU-Cache-Lokalisierung näher liegen können. In einigen Ausführungsformen kann eine Idle-CPU bevorzugt versuchen, von einem gemeinsam genutzten Ringpuffer zu stehlen, der mit einer nicht Idle-CPU verbunden ist, die sich im selben Prozessorsockel wie die Idle-CPU befindet.
  • Wenn ein gemeinsamer Ringpuffer, von dem eine inaktive CPU Arbeit stehlen möchte, leer ist, kann die inaktive CPU zu einer anderen zufällig ausgewählten CPU gehen, von der sie stehlen möchte. Es sollte beachtet werden, dass, da jede CPU mit mindestens einem gemeinsamen Ringpuffer assoziiert ist/hat, auf den Threads gelegt werden können und von dem Threads gestohlen/genommen werden können, je mehr Hardware (CPUs) zu einem System hinzugefügt wird, desto mehr Skalierbarkeit möglich ist/je besser die Verarbeitungsgeschwindigkeit ist.
  • Wenn man bedenkt, dass der primäre Mechanismus, um eine bessere Leistung aus einem System herauszuholen, darin besteht, mehr CPUs hinzuzufügen, führt die entsprechende Hinzufügung von mehr gemeinsam genutzten Ringpuffern dazu, dass sich potenziell mehr CPUs die Threads dynamisch in ausgewogenerer Weise teilen, als es bei herkömmlichen Systemen möglich ist. Darüber hinaus führt das einfache Hinzufügen von mehr CPUs ohne einen sperrfreien Work-Stealing-Mechanismus, wie der hier beschriebene, tendenziell zu mehr Konflikten zwischen CPUs, die versuchen, dieselben Threads auszuführen, und zu mehr Latenz, da mehr CPU-Zyklen aufgrund von Sperren verpasst werden können. Gemäß verschiedenen Ausführungsformen gibt es keine Konflikte zwischen den CPUs in Bezug auf den gemeinsam genutzten Pufferring, außer beim Stehlen von Arbeit und/oder wenn ein Remote-Wake beteiligt ist. Insbesondere kann sich Remote-Wake auf eine Situation beziehen, in der eine CPU einen fertigen Thread aufgrund von Affinitätsbeschränkungen (oder aus einem anderen Grund) nicht auf ihren eigenen gemeinsamen Ringpuffer legen kann und der Thread daher auf den gemeinsamen Ringpuffer einer anderen CPU gelegt wird. Wenn die andere CPU zur gleichen Zeit auf denselben gemeinsamen Ringpuffer zugreift, kommt es zu einer Cache-Zeilen-Konkurrenz.
  • Wenn die Suche der Idle-CPU nach der Arbeit anderer CPUs, die sie stehlen kann, nicht zu anderen Threads führt, kann die Idle-CPU in den Ruhezustand gehen, bis neue Arbeit eintrifft. Dies bewahrt eine Idle-CPU davor, zu viele System-CPU-Zyklen zu verbrauchen. Wann eine Idle-CPU in den Ruhezustand geht, kann auf einer bestimmten Anzahl von CPU-Zyklen basieren, über die die CPU nach Arbeit fragt, z. B. einer Schwellenanzahl von CPU-Zyklen. In einigen Ausführungsformen kann ein prädiktiver Algorithmus verwendet werden, der den Zeitpunkt, zu dem eine inaktive CPU in den Ruhezustand geht, auf die Anzahl der CPU-Zyklen stützt, die sie zuvor benötigt hat, um Arbeit zu finden (zu stehlen). Es gibt noch andere denkbare Mechanismen, die verwendet werden können, um zu bestimmen, wie lange eine CPU nach Arbeit sucht und/oder wie lange es dauert, bis eine CPU in den Ruhezustand geht, ohne Arbeit zum Stehlen gefunden zu haben.
  • Wenn eine nicht leerlaufende CPU, z. B. CPU 200, keine Arbeit mehr hat, d. h. ihre lokale Laufwarteschlange 205 leer wird, prüft die CPU zunächst ihren gemeinsamen Ringpuffer, in diesem Fall den gemeinsamen Ringpuffer 215, um festzustellen, ob irgendwelche darin eingereihten Threads darauf warten, auf CPU 200 zu laufen. Wenn dies der Fall ist, zieht die CPU 200 einen Stapel von Threads, die darauf warten, ausgeführt zu werden, und stellt sie in die lokale Warteschlange 205. CPU 200 kann dann jeden Thread in Prioritätsreihenfolge ausführen.
  • In wird eine Polling-Architektur beschrieben. Ein Poller kann sich auf eine Callback-Funktion beziehen, die von dem hier beschriebenen Scheduler periodisch aufgerufen wird, um eine Bedingung zu prüfen, z. B. Arbeit, die ausgeführt werden muss. Poller können oft Interrupt-Service-Routinen ersetzen, die typischerweise nur im Kernel-Mode-Code existieren.
  • Frühere Kernel-Treiber nutzten Geräte-Interrupts, aber Interrupts direkt zu einem Benutzermodus waren nicht machbar, daher wurde ein Polling-Modell verwendet, bei dem Polling-Routinen so wenig wie möglich taten, nur um festzustellen, ob zu erledigende Arbeit vorhanden ist, und wenn ja, konnte ein Thread der „unteren Hälfte“ ausgelöst werden, um die eigentliche Arbeit auszuführen. Poller unterscheiden sich von Threads dadurch, dass sie typischerweise aus einer einzelnen Routine bestehen, die wiederholt aufgerufen wird, typischerweise bis zum Abschluss läuft und dann zum Scheduler zurückkehrt, obwohl Poller in Threads implementiert werden können. So führt das oben erwähnte Polling-Modell Poller-Threads auf dedizierten CPUs in jedem Prozessorsockel aus. Die Threads der unteren Hälfte könnten auf anderen CPUs im selben physischen Prozessorsockel wie die Poller-Threads ausgeführt werden (neben anderen Threads, aber mit höherer Priorität). Ähnlich wie bei den oben beschriebenen Problemen mit CPU-Engpässen kann die Verwendung dedizierter CPUs für Poller-Threads jedoch zu einer Unter- oder Überversorgung von CPU-Ressourcen für Polling führen.
  • Dementsprechend verwendet die in dargestellte und weiter unten beschriebene Polling-Architektur ein verteiltes Schema, bei dem die Polling-Arbeit mit der „regulären“ Thread-Ausführung über alle CPUs in einem System verschachtelt werden kann. Auf diese Weise kann ein System leichter skaliert werden, indem das Polling dynamisch über alle CPUs in einem Prozessorsockel verteilt wird, im Gegensatz zur Verwendung eines dedizierten Satzes von CPUs für die Handhabung des Pollings.
  • In einigen Ausführungsformen kann ein gemeinsam genutztes Array von Pollern 240 in einem System implementiert werden, wobei jeder der Poller in dem Array mit einem bestimmten Sockel, z. B. einem NUMA-Sockel, verknüpft sein kann. Wie in dargestellt, umfasst ein gemeinsam genutztes Array von Pollern 240 beispielsweise Poller 240a, 240b und 240c, von denen jeder bei einem bestimmten Prozessorsockel registriert sein kann, den alle CPUs im Prozessorsockel lesen können. Jeder der Poller 240a, 240b und 24c kann ein atomares Flag haben, das anzeigt, ob er auf einer bestimmten CPU läuft oder nicht, d. h. ein Lauf-Flag, das als atomare Variable implementiert werden kann. Es sollte beachtet werden, dass alle Änderungen an einem gemeinsam genutzten Poller-Array, wie z. B. dem gemeinsam genutzten Poller-Array 240, durchgeführt werden können, wenn Poller registriert oder unregistriert sind (was typischerweise selten vorkommt), und wobei ein Schema vom Typ Read-Copy-Update (RCU) verwendet wird.
  • Jedes Mal, wenn ein Thread eine CPU, in diesem Beispiel die lokale CPU 200, an den Scheduler/Scheduling-Algorithmus zurückgibt, versucht der Scheduler, einen Poller auszuführen, bevor er den nächsten auszuführenden Thread einplant. Das heißt, wenn die lokale CPU 200 einen Thread oder eine Thread-Scheduling-Schleife erfährt/ausführt, kann ein Poller zufällig aus dem gemeinsamen Poller-Array 240 ausgewählt werden. Einer der Poller 240a, 240b oder 240c kann ausgewählt werden, z. B. Poller 240a, und es wird versucht, das Laufkennzeichen dieses Pollers 240a mithilfe einer CAS-Operation (Compare-and-Swap) atomar zu setzen. Wenn die CAS-Operation erfolgreich ist, wird Poller 240a als auf der lokalen CPU 200 ausgeführt „beansprucht“, und keine andere CPU kann Poller 240a parallel ausführen. Die lokale CPU 200 kann dann den Poller 240a ausführen, sein Laufkennzeichen löschen und ihn freigeben, damit er an anderer Stelle wieder läuft (Ausführung auf einer anderen CPU). Wenn die CAS-Operation fehlschlägt, kann die lokale CPU 200 entweder erneut versuchen, den Poller-Thread mit einem anderen zufällig ausgewählten Poller auszuführen, oder die lokale CPU 200 kann die Ausführung des Poller-Threads (für den Moment) aufgeben und den nächsten auszuführenden Thread planen (wie oben beschrieben). Es ist zu beachten, dass die Anzahl der Versuche, einen Poller auszuführen, zur Laufzeit konfiguriert werden kann. In einigen Ausführungsformen kann der Versuch, einen Poller pro Planungszyklus laufen zu lassen, die Standardbetriebsart sein. Auf diese Weise können alle CPUs in einem Prozessorsockel das Dispatching mehrerer Poller mit minimalem Overhead effizient untereinander aufteilen. Die Kosten für den Versuch, einen Poller zu finden, der ausgeführt werden soll, können einfach darin bestehen, einen zufälligen Index im gemeinsam genutzten Poller-Array zu generieren, z. B. das gemeinsam genutzte Poller-Array 240, und dann einen einzelnen CAS-Befehl auszuführen, um zu versuchen, einen Poller bei diesem Index zu beanspruchen. Diese anfallenden Kosten sind billig genug, dass die Poller-Auswahl zwischen jedem Thread-Ausführungs-/Ertragszyklus erfolgen kann, ohne eine signifikante zusätzliche Verarbeitungslatenz im Scheduler einzuführen.
  • Es ist zu beachten, dass die Verwendung der oben genannten Polling-Architektur dazu führen kann, dass ein Poller mit geringerer Wahrscheinlichkeit ausgewählt wird, wenn der Poller für eine gewisse Zeit keine Arbeit gefunden hat. Dadurch kann das Polling eine Präferenz für aktivere Geräte aufweisen. Zum Beispiel kann ein Speicherarray auf einem bestimmten Frontend- oder Backend-Geräteport(s) eine höhere Aktivität aufweisen, während andere Ports im Leerlauf sind. Anstatt Zeit damit zu verschwenden, ungenutzte Ports zu oft abzufragen, können die Ressourcen besser für die Abfrage aktiver Ports genutzt werden, wodurch eine geringere Latenzzeit für Anfragen an diesen Ports erreicht wird. In einigen Ausführungsformen kann diese Bevorzugung aktiver Geräte durch die Implementierung eines Zählers für jeden Poller erreicht werden, bei dem ein Zähler basierend auf der Anzahl der Zyklen akkumuliert wird, in denen ein bestimmter Poller aufgerufen wurde, aber der Poller keine Arbeit gefunden hat, die er ausführen kann. Wenn der akkumulierte Zählerstand für einen bestimmten Poller einen Schwellenwert erreicht oder überschreitet, kann z. B. ein „Verzögerungsauftrag“-Zähler für diesen bestimmten Poller inkrementiert werden. Wenn andererseits ein zufällig ausgewählter Poller Arbeit findet, kann der Verzögerungsauftragszähler auf Null zurückgesetzt werden. Außerdem kann jede CPU, die eine Abfrage durchführt, eine Sequenznummer behalten, die jedes Mal inkrementiert werden kann, wenn die CPU versucht, einen Poller zur Ausführung zu finden (wie oben beschrieben). Wenn die CPU also einen Poller auswählt, z. B. wenn die lokale CPU 200 den Poller 240a auswählt, prüft die lokale CPU 200, ob ihre aktuelle Sequenznummer durch 2N teilbar ist, wobei sich N auf die Verzögerungsreihenfolge des ausgewählten Pollers (in diesem Fall Poller 240a) beziehen kann. Mit anderen Worten, die lokale CPU 200 kann prüfen, ob der folgende Ausdruck wahr ist:
    • (my_sequence_number MOD (1 << poller_delay_order)) == 0
  • Wenn der Ausdruck wahr ist, kann der ausgewählte Poller, z. B. Poller 240a, ausgeführt werden. Wenn der Ausdruck falsch ist, kann die lokale CPU 20 den Poller 240a überspringen und einen anderen Poller auswählen, in diesem Fall entweder Poller 240b oder Poller 240c. Ein solcher Mechanismus bzw. eine solche Logik führt dazu, dass ein Poller in der Regel etwa alle 2N Mal ausgeführt wird, wenn er in Betracht gezogen wird. Wenn N==0 (der Poller ist aktiv), wird der Poller jedes Mal ausgeführt, wenn er in Betracht gezogen wird. Je länger ein Poller jedoch im Leerlauf ist, desto weiter erhöht sich sein Zähler für die Verzögerungsreihenfolge, und somit wird dieser Poller mit der Zeit weniger häufig ausgeführt. Es sollte beachtet werden, dass eine maximale Obergrenze oder ein Schwellenwert festgelegt werden kann, bis zu dem der Verzögerungsauftrag wachsen/akkumulieren kann, so dass jeder Poller dennoch mit einer angemessenen Häufigkeit ausgeführt wird.
  • ist ein Beispiel für ein Computergerät 300 in Übereinstimmung mit Ausführungsformen der vorliegenden Offenbarung. Wo Vorgänge und Funktionalität der Rechenvorrichtung 300 gleich oder ähnlich zu denen sind, die in Bezug auf besprochen wurden, sollte die Beschreibung als zutreffend interpretiert werden. Beispielsweise kann die Rechenvorrichtung 300 eine Ausführungsform eines Knotens, eines Knoten-Controllers, einer CPU wie der CPU 10 oder 30 sein. Die Rechenvorrichtung 300 umfasst einen oder mehrere Hardwareprozessoren 302, die eine oder mehrere Zentraleinheiten (CPUs), halbleiterbasierte Mikroprozessoren und/oder andere Hardwarevorrichtungen sein können, die zum Abrufen und Ausführen von Anweisungen geeignet sind, die in einem maschinenlesbaren Speichermedium 304 gespeichert sind. Der eine oder die mehreren Hardwareprozessoren 302 können Befehle, wie z. B. die Befehle 306-314, abrufen, dekodieren und ausführen, um Prozesse oder Operationen zum Bewirken von Fehlererkennung und -steuerung im Kontext von Kohärenzverzeichnis-Caches gemäß einer Ausführungsform zu steuern. Alternativ oder zusätzlich zum Abrufen und Ausführen von Befehlen können der eine oder die mehreren Hardware-Prozessoren 302 eine oder mehrere elektronische Schaltungen enthalten, die elektronische Komponenten zum Ausführen der Funktionalität eines oder mehrerer Befehle enthalten, wie z. B. ein Field Programmable Gate Array (FPGA), eine anwendungsspezifische integrierte Schaltung (ASIC) oder andere elektronische Schaltungen.
  • Der eine oder die mehreren Hardware-Prozessoren 302 sind so konfiguriert, dass sie Anweisungen ausführen, die auf einem maschinenlesbaren Medium 304 gespeichert sind. Bei dem maschinenlesbaren Medium 304 kann es sich um einen oder mehrere Typen von nichttransitorischen Computerspeichermedien handeln. Nicht einschränkende Beispiele sind: Flash-Speicher, Solid-State-Speichergeräte (SSDs), ein Storage Area Network (SAN), Wechselspeicher (z. B. Memory-Stick, CD, SD-Karten usw.) oder interner Computer-RAM oder -ROM, neben anderen Arten von Computer-Speichermedien. Die auf dem maschinenlesbaren Medium 304 gespeicherten Anweisungen können verschiedene Unteranweisungen zur Ausführung der durch die identifizierten Funktionen verkörperten Funktion enthalten.
  • Der eine oder die mehreren Hardware-Prozessoren 302 können die Anweisung 306 ausführen, um Threads in einer lokalen Laufwarteschlange auszuführen. Wie oben erwähnt, kann eine CPU, z. B. die lokale CPU 200 ( , auszuführende Threads in einer lokalen Laufwarteschlange, z. B. der lokalen Laufwarteschlange 205, platzieren, die spezifisch für die CPU ist (was bedeutet, dass andere CPUs keine Arbeit für Threads in der lokalen Laufwarteschlange einer anderen CPU stehlen oder ausführen können. In einigen Ausführungsformen kann die CPU die Threads in der lokalen Laufwarteschlange in Prioritätsreihenfolge ausführen.
  • Der eine oder die mehreren Hardwareprozessoren 302 können die Anweisung 308 ausführen, um einen gemeinsam genutzten Ringpuffer nach dem Löschen der lokalen Warteschlange zu prüfen. Wenn die lokale CPU 200 beispielsweise keine auszuführenden Threads mehr in der lokalen Warteschlange 205 hat, ist sie zu einer Leerlauf-CPU geworden, und die lokale CPU 200 kann den gemeinsamen Ringpuffer 215 prüfen, auf den sie Zugriff hat. Die lokale CPU 200 prüft den gemeinsam genutzten Ringpuffer 215, um festzustellen, ob es Threads gibt, die von der lokalen CPU 200 ausgeführt werden sollen, z. B. kann ein bestimmter Thread bzw. können bestimmte Threads eine bestimmte Affinität zur lokalen CPU 200 haben. Wenn es keine bestimmten Threads für die lokale CPU 200 gibt, die speziell ausgeführt werden sollen, kann die lokale CPU 200 alle Threads aus dem gemeinsamen Ringpuffer 215 stehlen, die sie ausführen kann. Das heißt, die lokale CPU 200 kann alle Threads stehlen, die eine Affinität zu einer Gruppe von CPUs haben, zu der die lokale CPU 200 gehört, eine bestimmte NUMA-Affinität oder überhaupt keine Affinität haben (d. h. jede verfügbare CPU kann den/die Threads ausführen). Es versteht sich von selbst, dass andere CPUs im Leerlauf, wie z. B. die CPU 230 im Leerlauf, ebenfalls den gemeinsamen Ringpuffer überprüfen können, um festzustellen, ob sie Threads stehlen können.
  • Dementsprechend können der eine oder die mehreren Hardwareprozessoren 302 die Anweisung 310 ausführen, um einen Stapel von Threads aus dem gemeinsam genutzten Ringpuffer zu entfernen. Zum Beispiel kann die lokale CPU 200 einen Stapel von Threads, die sie ausführen darf, aus dem gemeinsamen Ringpuffer entfernen. Der eine oder die mehreren Hardwareprozessoren 302 können ferner die Anweisung 312 ausführen, um den Stapel von Threads in die lokale Laufwarteschlange zu stellen. Das heißt, die lokale CPU 200 kann diesen Stapel von Threads, der aus der Warteschlange entfernt wurde, in ihre eigene lokale Warteschlange 205 stellen, damit er ausgeführt wird, z. B. in der Reihenfolge der Priorität. Der eine oder die mehreren Hardware-Prozessoren 302 können die Anweisung 312 ausführen, um den Stapel von Threads auszuführen/zu starten. Nun, da der entnommene Stapel von Threads, den die lokale CPU 200 aus dem gemeinsamen Ringpuffer 215 entnommen hat, ausgeführt werden kann, kann die lokale CPU 200 einen Thread ausführen, bis der Thread nachgibt, einen nachfolgenden Thread ausführen und so weiter.
  • ist ein Beispiel für ein Computergerät 400 in Übereinstimmung mit Ausführungsformen der vorliegenden Offenbarung. Wo Vorgänge und Funktionalität der Rechenvorrichtung 400 gleich oder ähnlich zu denen sind, die in Bezug auf erörtert werden, sollte die Beschreibung als zutreffend interpretiert werden. Beispielsweise kann die Rechenvorrichtung 400 eine Ausführungsform eines Knotens, eines Knoten-Controllers, einer CPU wie der CPU 10 oder 30 sein. Die Rechenvorrichtung 400 umfasst einen oder mehrere Hardwareprozessoren 402, die eine oder mehrere Zentraleinheiten (CPUs), halbleiterbasierte Mikroprozessoren und/oder andere Hardwarevorrichtungen sein können, die zum Abrufen und Ausführen von Anweisungen geeignet sind, die in einem maschinenlesbaren Speichermedium 404 gespeichert sind. Der eine oder die mehreren Hardwareprozessoren 402 können Befehle, wie z. B. die Befehle 406-414, abrufen, dekodieren und ausführen, um Prozesse oder Operationen zum Bewirken von Fehlererkennung und -steuerung im Kontext von Kohärenzverzeichnis-Caches gemäß einer Ausführungsform zu steuern. Alternativ oder zusätzlich zum Abrufen und Ausführen von Befehlen können der eine oder die mehreren Hardware-Prozessoren 402 eine oder mehrere elektronische Schaltungen enthalten, die elektronische Komponenten zum Ausführen der Funktionalität eines oder mehrerer Befehle enthalten, wie z. B. ein Field Programmable Gate Array (FPGA), eine anwendungsspezifische integrierte Schaltung (ASIC) oder andere elektronische Schaltungen.
  • Der eine oder die mehreren Hardware-Prozessoren 402 sind so konfiguriert, dass sie Anweisungen ausführen, die auf einem maschinenlesbaren Medium 404 gespeichert sind. Bei dem maschinenlesbaren Medium 404 kann es sich um einen oder mehrere Typen von nichttransitorischen Computerspeichermedien handeln. Nicht einschränkende Beispiele sind: Flash-Speicher, Solid-State-Speichergeräte (SSDs), ein Storage Area Network (SAN), Wechselspeicher (z. B. Memory-Stick, CD, SD-Karten usw.) oder interner Computer-RAM oder -ROM, neben anderen Arten von Computerspeichermedien. Die auf dem maschinenlesbaren Medium 404 gespeicherten Anweisungen können verschiedene Unteranweisungen zur Ausführung der durch die identifizierten Funktionen verkörperten Funktion enthalten.
  • Der eine oder die mehreren Hardware-Prozessoren 402 können die Anweisung 406 ausführen, um eine Vielzahl von Pollern in einem gemeinsamen Poller-Array zu gruppieren. Wie oben beschrieben und ähnlich wie bei der Platzierung von Threads in einem gemeinsam genutzten Pufferring, damit ungenutzte CPUs Arbeit stehlen können, können Poller, z. B. Poller 240a-240c ( , in einem gemeinsam genutzten Poller-Array 240 zusammengefasst werden, um von einer CPU, z. B. der lokalen CPU 200, zur Ausführung ausgewählt zu werden, um Polling-Threads dynamisch auf die CPUs zu verteilen. Jedem Poller im gemeinsam genutzten Poller-Array kann ein Atomic Running Flag zugewiesen werden.
  • Die Verwendung eines atomaren Laufkennzeichens ermöglicht die zufällige Auswahl eines Pollers, wobei mit einer CAS-Operation versucht werden kann, das Laufkennzeichen eines ausgewählten Pollers atomar zu setzen. Die mehreren Hardware-Prozessoren 402 können die Anweisung 408 ausführen, um einen ersten Poller aus der Vielzahl der Poller zufällig auszuwählen und zu versuchen, den ersten Poller auszuführen. Wenn die CAS-Operation erfolgreich ist und die CPU den ersten Poller zur Ausführung anfordern kann. Wie oben beschrieben, kann eine CPU versuchen, einen Poller zwischen der Planung der Ausführung von Threads auszuführen.
  • So können der eine oder die mehreren Hardware-Prozessoren 402 die Anweisung 410 ausführen, um den ersten Poller auszuführen, nachdem der erste Poller erfolgreich zur Ausführung angefordert wurde. Nach der Ausführung des ersten Pollers kann die CPU den ersten Poller freigeben, so dass er zufällig zur Ausführung durch z. B. eine andere CPU ausgewählt werden kann.
  • Andererseits, wenn die CAS-Operation fehlschlägt und der erste Poller nicht zur Ausführung angefordert werden kann, hat die CPU gemäß einigen Ausführungsformen zwei Möglichkeiten. Das heißt, der eine oder die mehreren Hardwareprozessoren 402 können die Anweisung 412 ausführen, um entweder zufällig einen zweiten Poller aus der Vielzahl von Pollern auszuwählen und zu versuchen, den zweiten Poller auszuführen, oder der eine oder die mehreren Hardwareprozessoren 402 können zur Planung eines auszuführenden Threads zurückkehren. Wiederum kann der auszuführende Thread ein nächster oder nachfolgender Thread sein, wobei daran erinnert wird, dass die Polling-Architektur zwischen der Thread-Planung, wie oben offenbart, verschachtelt ist.
  • zeigt ein Blockdiagramm eines Beispiel-Computersystems 500, in dem verschiedene der hier beschriebenen Ausführungsformen implementiert werden können. Das Computersystem 500 umfasst einen Bus 502 oder einen anderen Kommunikationsmechanismus zur Übermittlung von Informationen, einen oder mehrere mit dem Bus 502 gekoppelte Hardware-Prozessoren 504 zur Verarbeitung von Informationen. Der/die Hardware-Prozessor(en) 504 kann/können z. B. ein oder mehrere Allzweck-Mikroprozessoren sein.
  • Das Computersystem 500 umfasst auch einen Hauptspeicher 506, wie z. B. einen Speicher mit wahlfreiem Zugriff (RAM), einen Cache und/oder andere dynamische Speichergeräte, die mit dem Bus 502 verbunden sind, um Informationen und Anweisungen zu speichern, die vom Prozessor 504 ausgeführt werden sollen. Der Hauptspeicher 506 kann auch zum Speichern von temporären Variablen oder anderen Zwischeninformationen während der Ausführung von Anweisungen verwendet werden, die vom Prozessor 504 ausgeführt werden sollen. Solche Anweisungen, wenn sie in Speichermedien gespeichert sind, auf die der Prozessor 504 zugreifen kann, machen das Computersystem 500 zu einer Spezialmaschine, die so angepasst ist, dass sie die in den Anweisungen angegebenen Operationen ausführt.
  • Das Computersystem 500 umfasst außerdem einen Festwertspeicher (ROM) 508 oder ein anderes statisches Speichergerät, das mit dem Bus 502 verbunden ist, um statische Informationen und Anweisungen für den Prozessor 504 zu speichern. Ein Speichergerät 510, z. B. eine Magnetplatte, eine optische Platte oder ein USB-Stick (Flash-Laufwerk) usw., ist vorgesehen und mit dem Bus 502 gekoppelt, um Informationen und Anweisungen zu speichern.
  • Im Allgemeinen kann sich das Wort „Komponente“, „System“, „Datenbank“ und dergleichen, wie es hier verwendet wird, auf eine in Hardware oder Firmware verkörperte Logik oder auf eine Sammlung von Softwareanweisungen beziehen, die möglicherweise Ein- und Ausstiegspunkte haben und in einer Programmiersprache wie z. B. Java, C oder C++ geschrieben sind. Eine Softwarekomponente kann kompiliert und zu einem ausführbaren Programm verknüpft werden, in einer dynamischen Link-Bibliothek installiert werden oder in einer interpretierten Programmiersprache wie z. B. BASIC, Perl oder Python geschrieben sein. Softwarekomponenten können von anderen Komponenten oder von sich selbst aus aufrufbar sein und/oder als Reaktion auf erkannte Ereignisse oder Interrupts aufgerufen werden. Softwarekomponenten, die für die Ausführung auf Computergeräten konfiguriert sind, können auf einem computerlesbaren Medium, wie z. B. einer Compact Disc, einer digitalen Video-Disc, einem Flash-Laufwerk, einer Magnetplatte oder einem anderen greifbaren Medium, oder als digitaler Download bereitgestellt werden (und können ursprünglich in einem komprimierten oder installierbaren Format gespeichert sein, das vor der Ausführung eine Installation, Dekomprimierung oder Entschlüsselung erfordert). Ein solcher Softwarecode kann teilweise oder vollständig auf einer Speichervorrichtung des ausführenden Computergeräts gespeichert werden, um von dem Computergerät ausgeführt zu werden. Softwareanweisungen können in Firmware, wie z. B. einem EPROM, eingebettet sein. Es versteht sich von selbst, dass Hardware-Komponenten aus angeschlossenen Logikeinheiten, wie Gattern und Flipflops, bestehen können und/oder aus programmierbaren Einheiten, wie programmierbaren Gate-Arrays oder Prozessoren, zusammengesetzt sein können.
  • Das Computersystem 500 kann die hier beschriebenen Techniken unter Verwendung von kundenspezifischer festverdrahteter Logik, einem oder mehreren ASICs oder FPGAs, Firmware und/oder Programmlogik implementieren, die in Kombination mit dem Computersystem das Computersystem 500 zu einer Spezialmaschine macht oder programmiert. Gemäß einer Ausführungsform werden die hierin beschriebenen Techniken vom Computersystem 500 als Reaktion auf den/die Prozessor(en) 504 ausgeführt, der/die eine oder mehrere Sequenzen von einer oder mehreren Anweisungen ausführt/ausführen, die im Hauptspeicher 506 enthalten sind. Solche Anweisungen können in den Hauptspeicher 506 von einem anderen Speichermedium, wie z. B. dem Speichergerät 510, eingelesen werden. Die Ausführung der im Hauptspeicher 506 enthaltenen Befehlssequenzen veranlasst den/die Prozessor(en) 504, die hier beschriebenen Prozessschritte auszuführen. In alternativen Ausführungsformen können fest verdrahtete Schaltungen anstelle von oder in Kombination mit Softwareanweisungen verwendet werden.
  • Der Begriff „nicht-transitorische Medien“ und ähnliche Begriffe, wie sie hier verwendet werden, beziehen sich auf alle Medien, die Daten und/oder Befehle speichern, die eine Maschine dazu veranlassen, auf eine bestimmte Weise zu arbeiten. Solche nichttransitorischen Medien können nichtflüchtige Medien und/oder flüchtige Medien umfassen. Zu den nichtflüchtigen Medien gehören z. B. optische oder magnetische Platten, wie das Speichergerät 510. Zu den flüchtigen Medien gehören dynamische Speicher, wie z. B. der Hauptspeicher 506. Gängige Formen von nichtflüchtigen Medien sind beispielsweise eine Diskette, eine flexible Platte, eine Festplatte, ein Solid-State-Laufwerk, ein Magnetband oder ein anderes magnetisches Datenspeichermedium, eine CD-ROM, ein anderes optisches Datenspeichermedium, ein beliebiges physikalisches Medium mit Lochmustern, ein RAM, ein PROM und EPROM, ein FLASH-EPROM, NVRAM, ein beliebiger anderer Speicherchip oder eine Speicherkassette sowie vernetzte Versionen derselben.
  • Nicht-transitorische Medien unterscheiden sich von Übertragungsmedien, können aber in Verbindung mit diesen verwendet werden. Übertragungsmedien sind an der Übertragung von Informationen zwischen nicht-transitiven Medien beteiligt. Zu den Übertragungsmedien gehören z. B. Koaxialkabel, Kupferdraht und Lichtwellenleiter, einschließlich der Drähte, aus denen der Bus 502 besteht. Übertragungsmedien können auch in Form von akustischen oder Lichtwellen auftreten, wie sie z. B. bei der Radiowellen- und Infrarot-Datenkommunikation erzeugt werden.
  • Wie hierin verwendet, kann der Begriff „oder“ sowohl in einem einschließenden als auch in einem ausschließenden Sinn verstanden werden. Darüber hinaus ist die Beschreibung von Ressourcen, Vorgängen oder Strukturen im Singular nicht so zu verstehen, dass der Plural ausgeschlossen wird. Bedingte Ausdrücke, wie z. B. „kann“, „könnte“, „könnte“ oder „darf“, sind, sofern nicht ausdrücklich anders angegeben oder im Kontext anders verstanden, im Allgemeinen so zu verstehen, dass bestimmte Ausführungsformen bestimmte Merkmale, Elemente und/oder Schritte enthalten, während andere Ausführungsformen diese nicht enthalten. Begriffe und Ausdrücke, die in diesem Dokument verwendet werden, und Variationen davon, sollten, sofern nicht ausdrücklich anders angegeben, als offen und nicht als einschränkend verstanden werden. Der Begriff „einschließlich“ sollte als Beispiel im Sinne von „einschließlich, ohne Einschränkung“ oder ähnlichem verstanden werden. Der Begriff „Beispiel“ wird verwendet, um exemplarische Beispiele für den diskutierten Gegenstand zu geben, nicht als eine erschöpfende oder einschränkende Liste davon. Die Begriffe „ein“ oder „ein“ sind im Sinne von „mindestens ein“, „ein oder mehrere“ oder ähnlichem zu verstehen. Das Vorhandensein von erweiternden Wörtern und Ausdrücken wie „einer oder mehrere“, „mindestens“, „aber nicht beschränkt auf“ oder anderen ähnlichen Ausdrücken in einigen Fällen ist nicht so zu verstehen, dass der engere Fall beabsichtigt oder erforderlich ist, wenn solche erweiternden Ausdrücke fehlen können.

Claims (20)

  1. Eine zentrale Verarbeitungseinheit (CPU), bestehend aus: eine Steuereinheit, die Befehle aus einer Speichereinheit extrahiert, wobei die Befehle die Steuereinheit dazu veranlassen: Threads ausführen, die in einer mit der CPU verknüpften lokalen Laufwarteschlange gehalten werden; nach dem Löschen der lokalen Warteschlange, Überprüfung eines Puffers, der von einer Gruppe von CPUs, einschließlich der CPU und zusätzlichen CPUs, gemeinsam genutzt wird; eine Charge von Threads, die der CPU oder einer der zusätzlichen CPUs der Gruppe von CPUs zugeordnet sind, aus der Warteschlange des Puffers nehmen; den Stapel von Threads in die lokale Run-Queue stellen; und den Stapel von Threads ausführen.
  2. Die CPU nach Anspruch 1, wobei sich die CPU und die eine oder mehrere andere CPUs im selben physikalischen Kern oder im selben NUMA-Sockel (Non-Uniform Memory Access) befinden.
  3. Die CPU nach Anspruch 2, wobei der Stapel von Threads eine Affinität für die CPU, den physikalischen Kern oder den NUMA-Sockel hat.
  4. Die CPU nach Anspruch 2, wobei die Anweisungen ferner die Steuereinheit veranlassen, Threads des Stapels von Threads auszuwählen, die mit der einen der zusätzlichen CPUs aus demselben NUMA-Sockel verbunden sind, bevor die eine der zusätzlichen CPUs aus einer verbleibenden Teilmenge der zusätzlichen CPUs ausgewählt wird, die sich in demselben physischen Kern, aber nicht in demselben NUMA-Sockel befinden.
  5. Die CPU nach Anspruch 1, wobei die Befehle ferner die Steuereinheit veranlassen, den Puffer auf alle Threads zu prüfen, die auf der CPU warten, um zu laufen, und die zu den Threads gehörenden Threads auszuführen, bevor der Stapel von Threads aus der Warteschlange entfernt wird, die einer der einen oder mehreren anderen CPUs zugeordnet ist.
  6. Die CPU nach Anspruch 1, wobei die Befehle ferner die Steuereinheit veranlassen, die eine der anderen CPUs zufällig auszuwählen, von der der Stapel von Threads zu entkoppeln ist.
  7. Die CPU nach Anspruch 6, wobei die Anweisungen ferner die Steuereinheit veranlassen, wiederholt eine Zufallsauswahl der nachfolgenden der anderen CPUs durchzuführen, von denen der Stapel von Threads abgehängt werden soll, wenn die eine der anderen CPUs, die zufällig ausgewählt wurde, nicht mit mindestens einem lauffähigen Thread verbunden ist, von dem ein Stapel von Threads abgehängt werden kann.
  8. Die CPU nach Anspruch 7, wobei die Befehle ferner die Steuereinheit veranlassen, bei Erreichen einer maximalen Anzahl von Zufallsauswahlversuchen in einen Ruhezustand einzutreten.
  9. Die CPU nach Anspruch 8, wobei die Anweisungen ferner die Steuereinheit veranlassen, zu bestimmen, ob eine Schwellenanzahl von Zufallsauswahlversuchen, die zu einem erfolglosen Stehlen von Threads aus dem Puffer führen, aufgetreten ist, um den Ruhezustand zu initiieren.
  10. Die CPU nach Anspruch 1, wobei die Anweisungen ferner die Steuereinheit veranlassen, jeden Thread des Stapels von Threads in Prioritätsreihenfolge auszuführen.
  11. Die CPU nach Anspruch 1, wobei die Anweisungen ferner die Steuereinheit veranlassen, einen ersten Poller aus einem gemeinsam genutzten Poller-Array zufällig auszuwählen, der nach der Ausführung des Stapels von Threads ausgeführt werden soll.
  12. Die CPU nach Anspruch 11, wobei die Befehle ferner die Steuereinheit veranlassen, den ersten Poller nach erfolgreicher Beanspruchung des ersten Pollers zur Ausführung auszuführen.
  13. Die CPU nach Anspruch 12, wobei die Anweisungen, die ferner die Steuereinheit veranlassen, den ersten Poller auszuführen, die Steuereinheit veranlassen, ein dem ersten Poller zugeordnetes Running-Flag zu löschen, wobei die Steuereinheit versucht, das Running-Flag unter Verwendung einer Compare-and-Swap-Operation im Anschluss an die Zufallsauswahl des ersten Pollers zu löschen.
  14. Die CPU nach Anspruch 13, wobei die Befehle ferner die Steuereinheit veranlassen, das Laufflag zu löschen, wenn der erste Poller aufgrund der erfolgreichen Vergleichs- und Vertauschungsoperation zur Ausführung aufgefordert wird.
  15. Die CPU nach Anspruch 13, wobei die Anweisungen ferner die Steuereinheit veranlassen, einen zweiten Poller des gemeinsam genutzten Poller-Arrays zufällig auszuwählen, der ausgeführt werden soll, oder zur Überprüfung des gemeinsam genutzten Puffers zurückzukehren, um einen weiteren Stapel von Threads aus der Warteschlange zu entfernen.
  16. Die CPU nach Anspruch 11, wobei die Befehle ferner die Steuereinheit veranlassen, einen Verzögerungsauftragszähler zu inkrementieren, der jedem Poller des gemeinsam genutzten Poller-Arrays zugeordnet ist, wenn ein Poller des gemeinsam genutzten Poller-Arrays zufällig ausgewählt wird, der ausgewählte Poller jedoch keine Arbeit zu verrichten hat.
  17. Die CPU nach Anspruch 16, wobei die Befehle ferner die Steuereinheit veranlassen, eine inkrementierbare Sequenznummer beizubehalten, wobei die Steuereinheit die Sequenznummer jedes Mal inkrementiert, wenn die Steuereinheit zufällig einen Poller des gemeinsam genutzten Poller-Arrays auswählt, so dass die Steuereinheit eine Präferenz für Poller des gemeinsam genutzten Poller-Arrays mit einer kleineren Verzögerungsreihenfolge aufweist.
  18. Die CPU nach Anspruch 17, wobei die Anweisungen ferner die Steuereinheit veranlassen, die Präferenz zu ignorieren, bis die Verzögerungsreihenfolge einen maximalen Verzögerungsreihenfolgewert erreicht oder überschreitet.
  19. Eine zentrale Verarbeitungseinheit (CPU), bestehend aus: eine Steuereinheit, die Befehle aus einer Speichereinheit extrahiert, wobei die Befehle die Steuereinheit dazu veranlassen: die Ausführung eines zusätzlichen Satzes von Threads zu planen, indem ein Puffer geprüft wird, der von einer Gruppe von CPUs, einschließlich der CPU und zusätzlicher CPUs, gemeinsam genutzt wird, nachdem ein aktueller Satz von Threads ausgeführt wurde, der in einer mit der CPU verbundenen lokalen Laufwarteschlange gehalten wird; die zusätzlichen Threads in die lokale Run-Queue stellen; den Stapel von Threads ausführen; vor der Planung der Ausführung eines zweiten zusätzlichen Satzes von Threads versuchen, einen Poller aus einem gemeinsamen Poller-Array der Gruppe von CPUs auszuwählen, der von der CPU ausgeführt werden soll.
  20. Die CPU nach Anspruch 19, wobei die Anweisungen ferner die Wiederholung des Versuchs, einen Poller des gemeinsamen Poller-Arrays auszuwählen, zwischen der Planung der Ausführung weiterer Sätze von Threads umfassen.
DE102021108963.8A 2020-08-31 2021-04-11 Sperrenfreier arbeitseinsatz thread scheduler Pending DE102021108963A1 (de)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US17/008,549 2020-08-31
US17/008,549 US11698816B2 (en) 2020-08-31 2020-08-31 Lock-free work-stealing thread scheduler

Publications (1)

Publication Number Publication Date
DE102021108963A1 true DE102021108963A1 (de) 2022-03-03

Family

ID=80221125

Family Applications (1)

Application Number Title Priority Date Filing Date
DE102021108963.8A Pending DE102021108963A1 (de) 2020-08-31 2021-04-11 Sperrenfreier arbeitseinsatz thread scheduler

Country Status (3)

Country Link
US (2) US11698816B2 (de)
CN (1) CN114116155A (de)
DE (1) DE102021108963A1 (de)

Families Citing this family (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US11630603B1 (en) 2021-09-28 2023-04-18 Hewlett Packard Enterprise Development Lp Hardware device polling using delay order
US11669471B2 (en) * 2021-10-21 2023-06-06 EMC IP Holding Company, LLC System and method for lockless aborting of input/output (IO) commands

Family Cites Families (19)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6735769B1 (en) * 2000-07-13 2004-05-11 International Business Machines Corporation Apparatus and method for initial load balancing in a multiple run queue system
US7159215B2 (en) * 2001-06-27 2007-01-02 Sun Microsystems, Inc. Termination detection for shared-memory parallel programs
US20030037091A1 (en) * 2001-08-09 2003-02-20 Kozo Nishimura Task scheduling device
US20060123423A1 (en) * 2004-12-07 2006-06-08 International Business Machines Corporation Borrowing threads as a form of load balancing in a multiprocessor data processing system
US8136111B2 (en) * 2006-06-27 2012-03-13 International Business Machines Corporation Managing execution of mixed workloads in a simultaneous multi-threaded (SMT) enabled system
US8032884B2 (en) * 2006-10-31 2011-10-04 Hewlett-Packard Development Company, L.P. Thread hand off
US20110276978A1 (en) * 2010-05-10 2011-11-10 Andrew Gaiarsa System and Method for Dynamic CPU Reservation
US9183109B2 (en) * 2010-05-25 2015-11-10 Intel Corporation Method and system for analyzing the performance of multi-threaded applications
US9411636B1 (en) * 2011-07-07 2016-08-09 Emc Corporation Multi-tasking real-time kernel threads used in multi-threaded network processing
US9892031B2 (en) * 2011-11-07 2018-02-13 Sap Se Lock-free scalable free list
CN106164881B (zh) * 2013-03-15 2022-01-14 英特尔公司 异构计算系统中的工作窃取
US10936369B2 (en) * 2014-11-18 2021-03-02 International Business Machines Corporation Maintenance of local and global lists of task control blocks in a processor-specific manner for allocation to tasks
US9342384B1 (en) * 2014-12-18 2016-05-17 Intel Corporation Function callback mechanism between a central processing unit (CPU) and an auxiliary processor
US20170031724A1 (en) * 2015-07-31 2017-02-02 Futurewei Technologies, Inc. Apparatus, method, and computer program for utilizing secondary threads to assist primary threads in performing application tasks
US9778961B2 (en) * 2015-09-14 2017-10-03 Qualcomm Incorporated Efficient scheduling of multi-versioned tasks
US10235182B2 (en) * 2017-06-20 2019-03-19 Palo Alto Research Center Incorporated System and method for hybrid task management across CPU and GPU for efficient data mining
US11388074B2 (en) * 2018-04-12 2022-07-12 Intel Corporation Technologies for performance monitoring and management with empty polling
CN110597606B (zh) * 2019-08-13 2022-02-18 中国电子科技集团公司第二十八研究所 一种高速缓存友好的用户级线程调度方法
US11256549B2 (en) * 2019-10-16 2022-02-22 EMC IP Holding Company LLC Method and apparatus for thread scheduling

Also Published As

Publication number Publication date
US20230315526A1 (en) 2023-10-05
US20220066831A1 (en) 2022-03-03
CN114116155A (zh) 2022-03-01
US11698816B2 (en) 2023-07-11

Similar Documents

Publication Publication Date Title
US7797704B2 (en) System and method for performing work by one of plural threads using a lockable resource
US7975271B2 (en) System and method for dynamically determining a portion of a resource for which a thread is to obtain a lock
DE602004012106T2 (de) Multikanal-DMA mit gemeinsamem FIFO-Puffer
DE102013214756B4 (de) Verfahren zum verwalten einer task-ausführung in einem mehrkernprozessor
DE4227345C2 (de) Verfahren zur Ablaufsteuerung von Prozessen in einem Mehrprozessor-Computersystem
DE102013208554B4 (de) Verfahren und System zum Managen verschachtelter Ausführungsströme
US8141089B2 (en) Method and apparatus for reducing contention for computer system resources using soft locks
DE112004001133T5 (de) Warteschlangen-Sperren mit Monitor-Memory-Wait
DE112010005821T5 (de) Kontextwechsel
DE112014002754T5 (de) Effiziente Aufgabenplanung unter Verwendung eines Sperrmechanismus
DE102012220267B4 (de) Rechenarbeitsverteilungs - Referenzzähler
DE102021108963A1 (de) Sperrenfreier arbeitseinsatz thread scheduler
DE102013208558A1 (de) Verfahren und System zur Verarbeitung verschachtelter Stream-Events
DE112012002465T5 (de) Grafikprozessor mit nicht blockierender gleichzeitiger Architektur
DE102010034555A1 (de) Bereitstellen von Zustandsspeicher in einem Prozessor für Systemmanagement-Modus
DE112010005473T5 (de) Opportunistisches multitasking
DE102017213160B4 (de) Kompilierung für knotenvorrichtungs-GPU-basierte Parallelverarbeitung
EP1168182A1 (de) Transientspeichersegmentsubsystem für ein paralleles Datenbanksystem
DE102013201178A1 (de) Steuern von Arbeitsverteilung für Verarbeitung von Tasks
DE112013000687T5 (de) Verteilte Funktionsausführung für Hybridsysteme
DE112011100098B4 (de) Effiziente Mehrkernverarbeitung von Ereignissen
DE102021127151A1 (de) Verfahren und system für libfabric atomics-basierte lockless cluster-wide shared memory access api in einem verteilten system
DE112017007865T5 (de) Netzgebundener shuffle-datenspeicher
DE102010050432A1 (de) Verfahren, um eine Halbleiterlaufwerk-Leistung unter Verwendung eines programmierbaren Bus-Arbiters zu verbessern
DE112016007538T5 (de) Technologie zur realisierung eines binärverzweigten non-volatile-memory-express-treibers

Legal Events

Date Code Title Description
R081 Change of applicant/patentee

Owner name: HEWLETT PACKARD ENTERPRISE DEVELOPMENT LP, SPR, US

Free format text: FORMER OWNER: HEWLETT PACKARD ENTERPRISE DEVELOPMENT LP, HOUSTON, TX, US

R082 Change of representative

Representative=s name: HL KEMPNER PATENTANWALT, RECHTSANWALT, SOLICIT, DE

Representative=s name: HL KEMPNER PATENTANWAELTE, SOLICITORS (ENGLAND, DE

R012 Request for examination validly filed