Parallelität gegen Parallelität

Sowohl Parallelität als auch Parallelität werden in Bezug auf Multithread-Programme verwendet, aber es gibt viel Verwirrung über die Ähnlichkeit und den Unterschied zwischen ihnen. Die große Frage in dieser Hinsicht: Ist Parallelität Parallelität oder nicht? Obwohl beide Begriffe ziemlich ähnlich erscheinen, aber die Antwort auf die obige Frage NEIN lautet, sind Parallelität und Parallelität nicht gleich. Wenn sie nicht gleich sind, was ist dann der grundlegende Unterschied zwischen ihnen?

In einfachen Worten, bei der Parallelität wird der Zugriff auf den gemeinsam genutzten Status von verschiedenen Threads aus verwaltet, und bei der Parallelität werden mehrere CPUs oder deren Kerne verwendet, um die Leistung der Hardware zu verbessern.

Parallelität im Detail

Parallelität ist, wenn sich zwei Aufgaben bei der Ausführung überschneiden. Es kann vorkommen, dass eine Anwendung gleichzeitig mehrere Aufgaben ausführt. Wir können es schematisch verstehen; Mehrere Aufgaben machen gleichzeitig Fortschritte:

Parallelitätsstufen

In diesem Abschnitt werden wir die drei wichtigen Ebenen der Parallelität in Bezug auf die Programmierung diskutieren -

Low-Level-Parallelität

In dieser Ebene der Parallelität werden atomare Operationen explizit verwendet. Wir können eine solche Parallelität nicht für die Anwendungserstellung verwenden, da sie sehr fehleranfällig und schwer zu debuggen ist. Selbst Python unterstützt eine solche Parallelität nicht.

Mittlere Parallelität

In dieser Parallelität werden keine expliziten atomaren Operationen verwendet. Es werden die expliziten Sperren verwendet. Python und andere Programmiersprachen unterstützen eine solche Parallelität. Meistens verwenden Anwendungsprogrammierer diese Parallelität.

Parallelität auf hoher Ebene

In dieser Parallelität werden weder explizite atomare Operationen noch explizite Sperren verwendet. Python hatconcurrent.futures Modul zur Unterstützung dieser Art von Parallelität.

Eigenschaften gleichzeitiger Systeme

Damit ein Programm oder ein gleichzeitiges System korrekt ist, müssen einige Eigenschaften erfüllt sein. Eigenschaften im Zusammenhang mit der Beendigung des Systems sind wie folgt:

Richtigkeitseigenschaft

Die Korrektheitseigenschaft bedeutet, dass das Programm oder das System die gewünschte richtige Antwort liefern muss. Um es einfach zu halten, können wir sagen, dass das System den Startprogrammstatus korrekt dem Endstatus zuordnen muss.

Sicherheitseigenschaft

Die Sicherheitseigenschaft bedeutet, dass das Programm oder das System in a bleiben muss “good” oder “safe” Zustand und tut nie etwas “bad”.

Lebendigkeitseigenschaft

Diese Eigenschaft bedeutet, dass ein Programm oder System muss “make progress” und es würde einen wünschenswerten Zustand erreichen.

Akteure gleichzeitiger Systeme

Dies ist eine gemeinsame Eigenschaft eines gleichzeitigen Systems, in dem mehrere Prozesse und Threads gleichzeitig ausgeführt werden können, um Fortschritte bei ihren eigenen Aufgaben zu erzielen. Diese Prozesse und Threads werden als Akteure des gleichzeitigen Systems bezeichnet.

Ressourcen gleichzeitiger Systeme

Die Akteure müssen die Ressourcen wie Speicher, Festplatte, Drucker usw. nutzen, um ihre Aufgaben auszuführen.

Bestimmte Regeln

Jedes gleichzeitige System muss über eine Reihe von Regeln verfügen, um die Art der von den Akteuren auszuführenden Aufgaben und den Zeitpunkt für jede Aufgabe zu definieren. Die Aufgaben könnten das Erfassen von Sperren, das Teilen von Speicher, das Ändern des Status usw. sein.

Barrieren gleichzeitiger Systeme

Bei der Implementierung gleichzeitiger Systeme muss der Programmierer die folgenden zwei wichtigen Punkte berücksichtigen, die die Hindernisse für gleichzeitige Systeme darstellen können:

Weitergabe von Daten

Ein wichtiges Problem bei der Implementierung der gleichzeitigen Systeme ist die gemeinsame Nutzung von Daten zwischen mehreren Threads oder Prozessen. Tatsächlich muss der Programmierer sicherstellen, dass Sperren die gemeinsam genutzten Daten schützen, damit alle Zugriffe darauf serialisiert werden und jeweils nur ein Thread oder Prozess auf die gemeinsam genutzten Daten zugreifen kann. Wenn alle Threads oder Prozesse versuchen, auf dieselben gemeinsam genutzten Daten zuzugreifen, werden nicht alle bis auf mindestens einen blockiert und bleiben inaktiv. Mit anderen Worten, wir können sagen, dass wir jeweils nur einen Prozess oder Thread verwenden können, wenn die Sperre in Kraft ist. Es kann einige einfache Lösungen geben, um die oben genannten Hindernisse zu beseitigen -

Einschränkung des Datenaustauschs

Die einfachste Lösung besteht darin, keine veränderlichen Daten gemeinsam zu nutzen. In diesem Fall müssen wir keine explizite Sperrung verwenden, und die Barriere der Parallelität aufgrund gegenseitiger Daten wäre gelöst.

Unterstützung bei der Datenstruktur

Oft müssen die gleichzeitigen Prozesse gleichzeitig auf dieselben Daten zugreifen. Eine andere Lösung als die Verwendung expliziter Sperren besteht darin, eine Datenstruktur zu verwenden, die den gleichzeitigen Zugriff unterstützt. Zum Beispiel können wir die verwendenqueueModul, das thread-sichere Warteschlangen bereitstellt. Wir können auch verwendenmultiprocessing.JoinableQueue Klassen für Multiprozessor-basierte Parallelität.

Unveränderliche Datenübertragung

Manchmal ist die von uns verwendete Datenstruktur, beispielsweise die Parallelitätswarteschlange, nicht geeignet. Dann können wir die unveränderlichen Daten übergeben, ohne sie zu sperren.

Veränderliche Datenübertragung

Nehmen wir in Fortsetzung der obigen Lösung an, wenn nur veränderbare Daten anstatt unveränderlicher Daten übergeben werden müssen, können wir veränderbare Daten übergeben, die schreibgeschützt sind.

Gemeinsame Nutzung von E / A-Ressourcen

Ein weiteres wichtiges Problem bei der Implementierung gleichzeitiger Systeme ist die Verwendung von E / A-Ressourcen durch Threads oder Prozesse. Das Problem tritt auf, wenn ein Thread oder Prozess die E / A so lange verwendet und der andere im Leerlauf sitzt. Wir können eine solche Barriere sehen, wenn wir mit einer E / A-schweren Anwendung arbeiten. Es kann anhand eines Beispiels verstanden werden, wie Seiten vom Webbrowser angefordert werden. Es ist eine schwere Anwendung. Wenn die Rate, mit der die Daten angefordert werden, langsamer ist als die Rate, mit der sie verbraucht werden, haben wir hier eine E / A-Barriere in unserem gleichzeitigen System.

Das folgende Python-Skript dient zum Anfordern einer Webseite und zum Abrufen der Zeit, die unser Netzwerk benötigt hat, um die angeforderte Seite abzurufen.

import urllib.request

import time

ts = time.time()

req = urllib.request.urlopen('http://www.tutorialspoint.com')

pageHtml = req.read()

te = time.time()

print("Page Fetching Time : {} Seconds".format (te-ts))

Nach dem Ausführen des obigen Skripts können wir die Zeit zum Abrufen der Seite wie unten gezeigt abrufen.

Ausgabe

Page Fetching Time: 1.0991398811340332 Seconds

Wir können sehen, dass die Zeit zum Abrufen der Seite mehr als eine Sekunde beträgt. Was ist nun, wenn wir Tausende verschiedener Webseiten abrufen möchten? Sie können verstehen, wie viel Zeit unser Netzwerk in Anspruch nehmen würde.

Was ist Parallelität?

Parallelität kann als die Kunst definiert werden, die Aufgaben in Unteraufgaben aufzuteilen, die gleichzeitig verarbeitet werden können. Es ist entgegengesetzt zu der oben diskutierten Parallelität, bei der zwei oder mehr Ereignisse gleichzeitig stattfinden. Wir können es schematisch verstehen; Eine Aufgabe ist in mehrere Unteraufgaben unterteilt, die wie folgt parallel verarbeitet werden können:

Beachten Sie die folgenden Punkte, um mehr über die Unterscheidung zwischen Parallelität und Parallelität zu erfahren:

Gleichzeitig aber nicht parallel

Eine Anwendung kann gleichzeitig, aber nicht parallel sein. Dies bedeutet, dass sie mehrere Aufgaben gleichzeitig verarbeitet, die Aufgaben jedoch nicht in Unteraufgaben unterteilt sind.

Parallel aber nicht gleichzeitig

Eine Anwendung kann parallel, aber nicht gleichzeitig sein. Dies bedeutet, dass sie jeweils nur für eine Aufgabe ausgeführt wird und die in Unteraufgaben aufgeschlüsselten Aufgaben parallel verarbeitet werden können.

Weder parallel noch gleichzeitig

Eine Anwendung kann weder parallel noch gleichzeitig sein. Dies bedeutet, dass jeweils nur eine Aufgabe bearbeitet wird und die Aufgabe niemals in Unteraufgaben unterteilt wird.

Sowohl parallel als auch gleichzeitig

Eine Anwendung kann sowohl parallel als auch gleichzeitig ausgeführt werden. Dies bedeutet, dass beide Aufgaben gleichzeitig ausgeführt werden und die Aufgabe in Unteraufgaben unterteilt ist, um sie parallel auszuführen.

Notwendigkeit der Parallelität

Wir können Parallelität erreichen, indem wir die Unteraufgaben auf verschiedene Kerne einer einzelnen CPU oder auf mehrere Computer verteilen, die innerhalb eines Netzwerks verbunden sind.

Berücksichtigen Sie die folgenden wichtigen Punkte, um zu verstehen, warum Parallelität erforderlich ist:

Effiziente Codeausführung

Mit Hilfe der Parallelität können wir unseren Code effizient ausführen. Dies spart Zeit, da derselbe Code in Teilen parallel ausgeführt wird.

Schneller als sequentielles Rechnen

Sequentielles Rechnen wird durch physikalische und praktische Faktoren eingeschränkt, aufgrund derer es nicht möglich ist, schnellere Rechenergebnisse zu erzielen. Auf der anderen Seite wird dieses Problem durch paralleles Rechnen gelöst und liefert schnellere Rechenergebnisse als sequentielles Rechnen.

Weniger Ausführungszeit

Die parallele Verarbeitung reduziert die Ausführungszeit des Programmcodes.

Wenn wir über ein reales Beispiel für Parallelität sprechen, ist die Grafikkarte unseres Computers das Beispiel, das die wahre Leistungsfähigkeit der Parallelverarbeitung hervorhebt, da sie Hunderte einzelner Verarbeitungskerne aufweist, die unabhängig voneinander arbeiten und gleichzeitig die Ausführung durchführen können. Aus diesem Grund können wir auch High-End-Anwendungen und Spiele ausführen.

Verständnis der Prozessoren für die Implementierung

Wir kennen Parallelität, Parallelität und den Unterschied zwischen ihnen, aber was ist mit dem System, auf dem es implementiert werden soll? Es ist sehr wichtig, das System zu verstehen, auf dem wir implementieren werden, da es uns den Vorteil gibt, beim Entwerfen der Software fundierte Entscheidungen zu treffen. Wir haben die folgenden zwei Arten von Prozessoren -

Single-Core-Prozessoren

Single-Core-Prozessoren können jeweils einen Thread ausführen. Diese Prozessoren verwendencontext switchingum alle erforderlichen Informationen für einen Thread zu einem bestimmten Zeitpunkt zu speichern und die Informationen später wiederherzustellen. Der Kontextwechselmechanismus hilft uns, innerhalb einer bestimmten Sekunde Fortschritte bei einer Reihe von Threads zu erzielen, und es sieht so aus, als würde das System an mehreren Dingen arbeiten.

Single-Core-Prozessoren bieten viele Vorteile. Diese Prozessoren benötigen weniger Strom und es gibt kein komplexes Kommunikationsprotokoll zwischen mehreren Kernen. Andererseits ist die Geschwindigkeit von Single-Core-Prozessoren begrenzt und für größere Anwendungen nicht geeignet.

Multi-Core-Prozessoren

Mehrkernprozessoren haben mehrere unabhängige Prozessoreinheiten, die auch als solche bezeichnet werden cores.

Solche Prozessoren benötigen keinen Kontextumschaltmechanismus, da jeder Kern alles enthält, was zum Ausführen einer Folge gespeicherter Anweisungen erforderlich ist.

Fetch-Decode-Execute-Zyklus

Die Kerne von Mehrkernprozessoren folgen einem Ausführungszyklus. Dieser Zyklus wird als bezeichnetFetch-Decode-ExecuteZyklus. Es umfasst die folgenden Schritte:

Holen

Dies ist der erste Schritt des Zyklus, bei dem Anweisungen aus dem Programmspeicher abgerufen werden.

Dekodieren

Kürzlich abgerufene Anweisungen würden in eine Reihe von Signalen umgewandelt, die andere Teile der CPU auslösen.

Ausführen

Dies ist der letzte Schritt, in dem die abgerufenen und die decodierten Anweisungen ausgeführt werden. Das Ergebnis der Ausführung wird in einem CPU-Register gespeichert.

Ein Vorteil hierbei ist, dass die Ausführung in Multi-Core-Prozessoren schneller ist als die von Single-Core-Prozessoren. Es ist für größere Anwendungen geeignet. Andererseits ist ein komplexes Kommunikationsprotokoll zwischen mehreren Kernen ein Problem. Mehrere Kerne benötigen mehr Strom als Single-Core-Prozessoren.