Es sind zwei Sätze, die dasselbe aus (sehr geringfügig) unterschiedlichen Blickwinkeln beschreiben. Parallele Programmierung beschreibt die Situation aus Sicht der Hardware - es gibt mindestens zwei Prozessoren (möglicherweise innerhalb eines einzelnen physischen Pakets), die parallel an einem Problem arbeiten. Die gleichzeitige Programmierung beschreibt die Dinge aus Sicht der Software genauer - zwei oder mehr Aktionen können genau gleichzeitig (gleichzeitig) ausgeführt werden.
Das Problem hierbei ist, dass die Leute versuchen, die beiden Sätze zu verwenden, um eine klare Unterscheidung zu treffen, wenn keiner wirklich existiert. Die Realität ist, dass die Trennlinie, die sie zu ziehen versuchen, seit Jahrzehnten verschwommen und undeutlich ist und im Laufe der Zeit immer undeutlicher geworden ist.
Was sie zu diskutieren versuchen, ist die Tatsache, dass die meisten Computer einst nur eine einzige CPU hatten. Wenn Sie mehrere Prozesse (oder Threads) auf dieser einzelnen CPU ausgeführt haben, hat die CPU jeweils nur einen Befehl von einem dieser Threads ausgeführt. Das Auftreten von Parallelität war eine Illusion - die CPU wechselte schnell genug zwischen der Ausführung von Anweisungen aus verschiedenen Threads, so dass es für die menschliche Wahrnehmung (für die weniger als 100 ms oder so augenblicklich aussehen) so aussah, als würde sie viele Dinge gleichzeitig tun.
Der offensichtliche Gegensatz dazu ist ein Computer mit mehreren CPUs oder eine CPU mit mehreren Kernen, sodass der Computer Anweisungen von mehreren Threads und / oder Prozessen genau zur gleichen Zeit ausführt. Code, der eines ausführt, kann / hat keinen Einfluss auf den Code, der im anderen ausgeführt wird.
Nun das Problem: Eine so klare Unterscheidung hat es so gut wie nie gegeben. Computerdesigner sind eigentlich ziemlich intelligent, daher haben sie vor langer Zeit festgestellt, dass (zum Beispiel) das Lesen einiger Daten von einem E / A-Gerät wie einer Festplatte (in Bezug auf CPU-Zyklen) lange gedauert hat Fertig. Anstatt die CPU währenddessen im Leerlauf zu lassen, haben sie verschiedene Möglichkeiten gefunden, wie ein Prozess / Thread eine E / A-Anforderung ausführen und Code von einem anderen Prozess / Thread auf der CPU ausführen kann, während die E / A-Anforderung abgeschlossen ist.
Lange bevor Multi-Core-CPUs zur Norm wurden, wurden Operationen von mehreren Threads parallel ausgeführt.
Das ist allerdings nur die Spitze des Eisbergs. Vor Jahrzehnten haben Computer begonnen, auch eine andere Ebene der Parallelität bereitzustellen. Als ziemlich intelligente Leute stellten Computerdesigner wieder fest, dass sie in vielen Fällen Anweisungen hatten, die sich nicht gegenseitig beeinflussten, so dass es möglich war, mehr als eine Anweisung aus demselben Stream gleichzeitig auszuführen. Ein frühes Beispiel, das ziemlich bekannt wurde, war der Control Data 6600. Dies war (mit ziemlich großem Abstand) der schnellste Computer der Welt, als er 1964 eingeführt wurde - und ein Großteil der gleichen grundlegenden Architektur wird heute noch verwendet. Es verfolgte die von jedem Befehl verwendeten Ressourcen und verfügte über eine Reihe von Ausführungseinheiten, die Befehle ausführten, sobald die Ressourcen verfügbar wurden, von denen sie abhingen. Dies war dem Design der neuesten Intel / AMD-Prozessoren sehr ähnlich.
Aber (wie die Werbespots sagten) warten - das ist noch nicht alles. Es gibt noch ein weiteres Designelement, das noch mehr Verwirrung stiftet. Es wurden einige verschiedene Namen vergeben (z. B. "Hyperthreading", "SMT", "CMP"), aber alle beziehen sich auf dieselbe Grundidee: eine CPU, die mehrere Threads gleichzeitig ausführen kann, wobei eine Kombination einiger Ressourcen verwendet wird sind für jeden Thread unabhängig und einige Ressourcen, die von den Threads gemeinsam genutzt werden. In einem typischen Fall wird dies mit der oben beschriebenen Parallelität auf Befehlsebene kombiniert. Dazu haben wir zwei (oder mehr) Sätze von Architekturregistern. Dann haben wir eine Reihe von Ausführungseinheiten, die Anweisungen ausführen können, sobald die erforderlichen Ressourcen verfügbar sind.
Dann kommen wir natürlich zu modernen Systemen mit mehreren Kernen. Hier liegen die Dinge auf der Hand, oder? Wir haben N (im Moment zwischen 2 und 256 oder so) separate Kerne, die alle gleichzeitig Befehle ausführen können. Wir haben also einen eindeutigen Fall von echter Parallelität - das Ausführen von Befehlen in einem Prozess / Thread funktioniert nicht. t Auswirkungen auf die Ausführung von Anweisungen in einem anderen.
Naja, so ungefähr. Selbst hier haben wir einige unabhängige Ressourcen (Register, Ausführungseinheiten, mindestens eine Cache-Ebene) und einige gemeinsam genutzte Ressourcen (normalerweise mindestens die niedrigste Cache-Ebene und definitiv die Speichercontroller und die Bandbreite zum Speicher).
Zusammenfassend lässt sich sagen, dass die einfachen Szenarien, die Menschen gerne zwischen gemeinsam genutzten Ressourcen und unabhängigen Ressourcen kontrastieren, im wirklichen Leben praktisch nie vorkommen. Wenn alle Ressourcen gemeinsam genutzt werden, erhalten wir so etwas wie MS-DOS, bei dem wir jeweils nur ein Programm ausführen können, und wir müssen die Ausführung eines Programms beenden, bevor wir das andere überhaupt ausführen können. Mit völlig unabhängigen Ressourcen haben wir N Computer, auf denen MS-DOS ausgeführt wird (ohne ein Netzwerk, um sie zu verbinden), ohne dass sie überhaupt etwas zwischen ihnen teilen können (denn wenn wir überhaupt eine Datei teilen können, ist das eine gemeinsam genutzte Ressource, a Verletzung der Grundvoraussetzung, dass nichts geteilt wird).
Jeder interessante Fall beinhaltet eine Kombination aus unabhängigen Ressourcen und gemeinsam genutzten Ressourcen. Jeder einigermaßen moderne Computer (und viele, die überhaupt nicht modern sind) hat zumindest die Fähigkeit, mindestens einige unabhängige Operationen gleichzeitig auszuführen, und fast alles, was anspruchsvoller ist als MS-DOS, hat dies zumindest ausgenutzt einem gewissen Grad.
Die schöne, saubere Trennung zwischen "gleichzeitig" und "parallel", die die Leute gerne zeichnen, existiert einfach nicht und hat es fast nie gegeben. Was Menschen gerne als "gleichzeitig" klassifizieren, beinhaltet normalerweise immer noch mindestens eine und oft mehrere verschiedene Arten der parallelen Ausführung. Was sie gerne als "parallel" klassifizieren, besteht häufig darin, Ressourcen gemeinsam zu nutzen und (zum Beispiel) einen Prozess die Ausführung eines anderen zu blockieren, während eine Ressource verwendet wird, die von beiden gemeinsam genutzt wird.
Menschen, die versuchen, klar zwischen "parallel" und "gleichzeitig" zu unterscheiden, leben in einer Fantasie von Computern, die es eigentlich nie gab.