Was ist eine Speichersperre?

Historisch gesehen wurden alle Computerprogramme absolut sequentiell geschrieben. Dies ist einfach zu lesen, zu schreiben und zu verstehen. Es ist auch für einen Computer einfach auszuführen und erfordert relativ einfache Hardware. Bei diesem Designparadigma bestehen die einzigen beiden Möglichkeiten zur Steigerung der Systemleistung darin, effizienteren Code zu schreiben und die CPU-Geschwindigkeit zu erhöhen. Die Steigerung der Code-Effizienz mag möglich sein, ist jedoch im Allgemeinen ein komplexer Prozess mit oft begrenzten Ergebnissen.

Jahrzehntelang konnte die Leistung verringert werden, indem auf neue, effizientere CPUs gewartet wurde. Wie das Mooresche Gesetz beschreibt, verdoppeln sich CPUs ungefähr alle zwei bis drei Jahre in ihrer Leistung. Leider sind die meisten dieser Leistungssteigerungen auf die Verwendung immer kleinerer Fertigungsknoten zurückzuführen. Dank Materialschwierigkeiten, die im Nanometerbereich arbeiten, hat die moderne Technologie Schwierigkeiten, die Knotengröße im historischen Tempo zu verringern.

Um dies zu umgehen, haben sich moderne CPU-Architekten dafür entschieden, mehrere Prozessorkerne zu CPUs hinzuzufügen. Jeder Prozessorkern kann unabhängig voneinander eine andere Aufgabe bearbeiten. Sie können zwar nicht dasselbe Problem kombinieren, aber sie können gleichzeitig an zwei Themen arbeiten. Diese grundlegende Architekturänderung bietet viel zusätzliche Leistung, kommt einzelnen Prozessen jedoch nicht direkt zugute, obwohl sie den Wettbewerb um Prozessorzeit reduziert.

Um Multi-Core-CPUs nutzen zu können, muss Code in Multi-Threading-Manier geschrieben werden. Jeder Thread kann dann gleichzeitig ausgeführt werden, wobei der Leistungsvorteil durch die Anzahl der verfügbaren Threads und CPU-Kerne skaliert wird. Dabei stößt man jedoch auf eine neue Herausforderung, die „Race Condition“.

Hinweis: Einige Aufgaben können nicht multithreaded sein, während andere massiv multithreaded sein können. Die möglichen Leistungsvorteile hängen von der geleisteten Arbeit ab.

Rennbedingungen

Multithreaded-Software kann mehrere Kerne nutzen. In diesen Gewässern lauern Gefahren, die bereit sind, den unerfahrenen Programmierer zu fangen. Eine Racebedingung kann auftreten, wenn zwei verschiedene Threads mit demselben Speicherbit interagieren.

Ein einfaches Beispiel könnten zwei Threads sein, die versuchen, eine Variable gleichzeitig zu überprüfen und zu inkrementieren. Nehmen wir an, a=0 . Zwei verschiedene Threads führen dann ihre Funktionen aus und prüfen irgendwann a und inkrementieren es um eins. Im Allgemeinen würden Sie erwarten, dass das Ergebnis zweier Threads, die eins zu null addieren, zwei ist. Meistens sollte dies der Fall sein. Sie können ein anderes Ergebnis erzielen, wenn beide Threads genau zum richtigen Zeitpunkt diese spezifische Funktionalität durchlaufen.

In diesem Fall liest der erste Thread den Wert von a . Bevor der erste Thread den Wert von a inkrementieren kann , liest ihn der zweite Thread. Jetzt addiert der erste Thread eins zu null, aber der zweite Thread glaubt bereits, dass der Wert null ist, und addiert eins zu null. Das Ergebnis davon ist, dass der Endwert von a 1 ist, nicht 2.

Rennen zum Worst-Case-Szenario

Auch wenn das obige Beispiel nicht besonders schlecht klingt, kann es dramatische Auswirkungen haben. Was ist, wenn der Wert von a die Betriebsart einer Maschine auswählt? Was ist, wenn bestimmte Betriebsmodi dieser Maschine gefährlich oder sogar lebensbedrohlich sein können?

Die Rennbedingungen müssen auch nicht so einfach sein. Beispielsweise kann es möglich sein, dass ein Thread einen Speicherabschnitt liest, während ein anderer Thread darauf schreibt. In diesem Fall kann der Lese-Thread eine seltsame Mischung der Daten von Vorher und Nachher erhalten. Nehmen wir an, die Prüfung ist eine einfache Wahr/Falsch-Prüfung.

Wenn die Variable zu Beginn des Lesevorgangs „true“ lautete, aber gerade mit dem Wort „false“ überschrieben wurde, könnte das Ergebnis des Lesevorgangs so etwas wie „trlse“ sein. Das ist nicht „wahr“ oder „falsch“. Keine der beiden Optionen in einer binären Auswahl zu sein, würde mit ziemlicher Sicherheit zum Absturz der Anwendung führen. Diese Speicherbeschädigung kann zu vielen Sicherheitsproblemen führen, z. B. Denial-of-Service und Rechteausweitung.

Sperren des Rennens

Es ist wichtig zu wissen, welche Speicherbits in einem Programm von verschiedenen Threads gemeinsam genutzt werden, um eine Race-Bedingung zu verhindern. Es muss nichts unternommen werden, wenn eine Variable immer nur von einem einzigen Thread gesteuert wird und zugänglich ist. Wenn zwei oder mehr Threads auf eine Variable zugreifen können, müssen Sie sicherstellen, dass alle Operationen auf diesem Speicherstück unabhängig voneinander ausgeführt werden.

Diese Unabhängigkeit wird durch ein Schloss erreicht. Im Code eines Programms müssen Sie eine Sperre setzen, wenn Sie eine Funktion schreiben, die auf einem gemeinsam genutzten Stück Speicher arbeitet. Diese Sperre hindert andere Threads daran, auf diesen Teil des Speichers zuzugreifen, bis die Sperre aufgehoben wird.

Das Schloss ist nicht die eleganteste Lösung. Zum einen hat es Speicher-Overheads. Es kann auch das Aufhängen eines Threads erzwingen und darauf warten, dass eine Sperre freigegeben wird. Je nach Situation kann es vorkommen, dass die Sperre sehr lange nicht oder gar nicht freigegeben wird. Im schlimmsten Fall könnte das Entsperren einer Sperre davon abhängen, dass etwas in einem anderen blockierten Thread passiert, was zu einem Deadlock führt.

Es ist wichtig, die Verwendung von Sperren zu optimieren. Sie können steuern, wie granular die Sperre ist. Wenn Sie beispielsweise Daten in einer Tabelle bearbeiten, können Sie die gesamte Tabelle oder nur die bearbeitete Zeile sperren. Das Sperren der gesamten Tabelle wäre eine Sperre mit grober Granularität. Es minimiert den Aufwand durch die Implementierung zu vieler Sperren, erhöht aber die Wahrscheinlichkeit, dass ein anderer Thread durch die Sperre blockiert wird. Das Sperren nur der Zeile wäre eine Sperre mit feiner Granularität. Es ist viel weniger wahrscheinlich, dass dies andere Threads stört, bedeutet aber, dass zerrissene Sperren erforderlich sind, was den Gesamtaufwand erhöht.

Abschluss

Eine Speichersperre ist ein Code-Tool, das verwendet wird, um Atomaritätsoperationen im Arbeitsspeicher in einer Umgebung mit mehreren Threads sicherzustellen. Indem Sie einen Speicherabschnitt sperren, bevor Sie ihn bearbeiten, können Sie sicher sein, dass aufgrund einer Racebedingung kein unerwartetes Verhalten auftreten kann. Speichersperren sind mit einem Speicher-Overhead verbunden, können aber auch Blockierungen verursachen.

Beim Blockieren versucht ein anderer Thread, auf einem gesperrten Pemory zu arbeiten. Der Thread sitzt dort blockiert, bis die Sperre aufgehoben wird. Dies kann zu Problemen führen, wenn zum Freigeben der Sperre ein anderer Thread etwas tun muss, da er möglicherweise blockiert wird, bevor er die Voraussetzung zum Freigeben der ihn blockierenden Sperre erfüllen kann. Speichersperren können vermieden werden, indem nicht blockierende Codes geschrieben werden. Dies kann jedoch komplex und weniger leistungsfähig sein als die Verwendung von Sperren. Vergessen Sie nicht, unten Ihre Kommentare zu hinterlassen.



Leave a Comment

So klonen Sie eine Festplatte

So klonen Sie eine Festplatte

Im modernen digitalen Zeitalter, in dem Daten ein wertvolles Gut sind, kann das Klonen einer Festplatte unter Windows für viele ein entscheidender Prozess sein. Dieser umfassende Leitfaden

Wie behebt man, dass der Treiber WUDFRd unter Windows 10 nicht geladen werden konnte?

Wie behebt man, dass der Treiber WUDFRd unter Windows 10 nicht geladen werden konnte?

Wird beim Booten Ihres Computers die Fehlermeldung angezeigt, dass der Treiber WUDFRd nicht auf Ihren Computer geladen werden konnte?

So beheben Sie den NVIDIA GeForce Experience-Fehlercode 0x0003

So beheben Sie den NVIDIA GeForce Experience-Fehlercode 0x0003

Tritt auf Ihrem Desktop der NVIDIA GeForce-Fehlercode 0x0003 auf? Wenn ja, lesen Sie den Blog, um herauszufinden, wie Sie diesen Fehler schnell und einfach beheben können.

Warum lässt sich mein Chromebook nicht einschalten?

Warum lässt sich mein Chromebook nicht einschalten?

Erhalten Sie Antworten auf die Frage: Warum lässt sich mein Chromebook nicht einschalten? In diesem hilfreichen Leitfaden für Chromebook-Benutzer.

So ändern Sie das Zifferblatt einer Fitbit Versa 4

So ändern Sie das Zifferblatt einer Fitbit Versa 4

Ändere das Zifferblatt deiner Fitbit Versa 4, um deiner Uhr jeden Tag kostenlos ein anderes Aussehen zu verleihen. Sehen Sie, wie schnell und einfach es geht.

Roomba stoppt, bleibt hängen und dreht sich um – Reparieren

Roomba stoppt, bleibt hängen und dreht sich um – Reparieren

Beheben Sie ein Problem, bei dem Ihr Roomba-Roboterstaubsauger anhält, hängenbleibt und sich ständig umdreht.

So ändern Sie die Grafikeinstellungen auf Steam Deck

So ändern Sie die Grafikeinstellungen auf Steam Deck

Das Steam Deck bietet ein robustes und vielseitiges Spielerlebnis direkt auf Knopfdruck. Allerdings, um Ihr Spiel zu optimieren und das bestmögliche zu gewährleisten

Was ist isolationsbasierte Sicherheit?

Was ist isolationsbasierte Sicherheit?

Wir werden uns mit einem Thema befassen, das in der Welt der Cybersicherheit immer wichtiger wird: Isolationsbasierte Sicherheit. Dieser Ansatz zu

How to Use Auto Clicker for Chromebook

How to Use Auto Clicker for Chromebook

Today, were going to delve into a tool that can automate repetitive clicking tasks on your Chromebook: the Auto Clicker. This tool can save you time and

Was ist SMPS?

Was ist SMPS?

Erfahren Sie, was SMPS ist und welche Bedeutung die verschiedenen Effizienzbewertungen haben, bevor Sie sich für ein SMPS für Ihren Computer entscheiden.