Parallel-Programmierung mit bekannten Mitteln

22. Oktober 2008, 11:58 Uhr | Chris Berg
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 2

Linux bietet SMP

In der Praxis kann ein Softwareentwickler jede der oben genannten Techniken allein oder in Kombination verwenden, um die Leistungsfähigkeit einer SMPbasierten Plattform für eine bestimmte Applikation zu verbessern. Es ließe sich sogar ein datenparalleles Array verteilter SMP-Server einrichten, von denen jeder eine Control-Flow-Pipeline enthält. Damit ein solches Schema aber effizient arbeitet, sind eine sehr hohe Auslastung und ein sehr großer Datensatz erforderlich.

In SoC-Systemen, in denen Parallelismus durch statische, physikalische Zerlegung von Tasks auf Prozessoren möglich ist (z.B. ein Prozessor-Core pro Eingangsport), lassen sich parallele Tasks auf die Prozessoren in Hardware zuweisen. Damit verringern sich zwar der Software-Overhead und die Codegröße, aber ein solches System ist wenig flexibel.

Auf gleiche Weise lässt sich eine Embedded-Applikation statisch in Clients und Server zerlegen, die über eine On-Chip-Verbindung kommunizieren. Die einzige Systemsoftware, die erforderlich ist, um das System zusammenzuhalten, wäre eine Instanz, die ein gemeinsames Protokoll für alle Prozessoren implementiert. Dieses Message-Passing-Protokoll bietet einen gewissen Abstraktionsgrad, um Systeme mit mehr oder weniger Prozessoren aufbauen zu können, die eine gemeinsame Basis an Applikationscode verarbeiten. Bei jeder Art von Konfiguration ist die Lastverteilung zwischen den Prozessoren aber genauso statisch wie die Hardware-Partitionierung. Für eine flexiblere parallele Systemprogrammierung ist eine Softwareverteilung der Tasks über ein Multiprozessorsystem mit gemeinsam genutzten Ressourcen erforderlich. Betriebssysteme für symmetrisches Multiprocessing betrachten ein System, wie der Name schon sagt, auf »symmetrische « Art und Weise.

passend zum Thema

Alle Prozessoren haben Zugriff auf den gleichen Speicher, die gleichen I/Os, den gleichen Betriebssystemzustand. Dies vereinfacht die Migration eines Programms von einem auf einen anderen Prozessor (Bild 4). Damit gestaltet sich die Lastverteilung insgesamt einfacher. Ohne zusätzliche Programmierung oder Systemverwaltung laufen Programme, die im Multitasking-Betrieb mit Zeitrahmen auf einer einzigen CPU abgearbeitet werden, nacheinander auf den verfügbaren CPUs eines SMP-Systems. Ein SMPScheduler (wie z.B. bei Linux) schaltet die Programme für die Prozessoren ein und aus, sodass alle Programme gleichläufig abgearbeitet werden. Eine Linux-Anwendung, die auf mehreren Prozessen abläuft, muss der Softwareentwickler nicht modifizieren, um die Vorteile des SMPParallelismus zu nutzen. Eine erneute Kompilierung ist in den meisten Fällen nicht erforderlich – ausgenommen bei Binaries, die mit Non-Thread-sicheren Bibliotheken statisch verlinkt waren. Eine SMP-Linux-Umgebung bietet eine Reihe von Werkzeugen, mit denen Entwickler die Aufteilung der Tasks auf die verfügbaren Prozessoren einstellen können. So lässt sich die Priorität der Tasks erhöhen oder herabstufen. Aber die Entwickler sind auch in der Lage, sie einzuschränken, um auf einer beliebigen Untermenge von Prozessoren zu laufen. Mit dem passenden Kernel-Support können die Tasks den Einsatz verschiedener Echtzeit-Scheduling-Systeme erfordern.

Unix-ähnliche Betriebssysteme erlaubten Applikationen schon immer, eine gewisse Kontrolle über die relative Scheduling-Priorität der Tasks zu übernehmen, selbst in Timesharing-Systemen mit nur einem Prozessor. Das herkömmliche Shell-Command und der System-Call wurden in Linux um ausführlichere Mechanismen erweitert, um die Task-Priorität, Task-Gruppen oder spezifischen Nutzer eines Systems zu handhaben – sofern es notwendig wird, das Verhalten des Betriebssystems vorauszusagen.

In Multiprozessor-Konfigurationen verfügt jede Linux-Task außerdem über einen Parameter, der festlegt, welcher Prozessorensatz die Task zeitlich einplant. Vorgabe ist, dass dieser Parameter alle Prozessoren im System umfasst. Wie auch bei der Priorität lässt sich die »Affinität« einer Task auf eine CPU durch ein »taskset«-Shell-Command oder durch eindeutige Systemaufrufe zur Manipulierung dieser »Affinität« steuern.

Symmetrisches Multiprocessing ermöglichen

Ein SMP-Systemmodell erfordert, dass alle Prozessoren den gesamten Speicher auf den gleichen Adressen erfassen. Für einfache Prozessoren mit niedriger Leistungsfähigkeit ist dies einfach zu erreichen. Man muss nur das Holen des Befehls (instruction fetch) sowie den gesamten Datenverkehr (Laden und Speichern) aller Prozessoren auf einen gemeinsamen Speicher- und I/O-Bus legen. Dieses einfache Modell versagt jedoch mit zunehmender Prozessor-zahl sehr schnell, da der Bus zum »Flaschenhals« wird. Und selbst in Systemen mit einem Prozessor schreiben die Bandbreiteanforderungen für Befehle und Daten hochleistungsfähiger Embedded-Cores vor, dass zwischen Hauptspeicher und Prozessor Cache-Speicher zum Einsatz kommen sollen. Ein System mit unabhängigen Caches pro Prozessor ist naturgemäß nicht mehr symmetrisches Multiprocessing. Enthält ein Prozessor-Cache die einzige Kopie des letzten Wertes einer Speicherstelle, ergibt sich eine einfache aber gefährliche Asymmetrie. Das System muss dann um Cache-Kohärenz-Protokolle erweitert werden, damit die Symmetrie wieder hergestellt ist. In einfachen Systemen, in denen alle Prozessoren mit einem gemeinsamen Bus verbunden sind, reicht es für alle Cache-Controller aus, den Bus zu überwachen, um festzustellen, welcher Cache die neueste Version einer bestimmten Speicherstelle besitzt. In fortschrittlicheren Systemen wie dem »MIPS32 1004K CPS« sind die Prozessoren über Punkt-zu-Punkt-Verbindungen zu einer »Switching Fabric« anstelle eines Busses mit dem Speicher verbunden. Cache-Kohärenz erfordert jedoch eine technisch ausgefeiltere Unterstützung. So ordnet der Kohärenzmanager des 1004K Speichertransaktionen und generiert die notwendigen Interventionssignale, um die Cache-Kohärenz zwischen mehreren 1004K-Prozessor-Chaches einzuhalten. Deshalb haben diese Prozessoren stets eine symmetrische Sicht auf den Speicher. Ein SMP-Betriebssystem wie Linux kann Tasks beliebig migrieren und Prozessorlasten dynamisch ausgleichen.

Bild04_af_17.jpg
Bild 4: SMP-Task-Verteilung bei einem Multiprozessorsystem

  1. Parallel-Programmierung mit bekannten Mitteln
  2. Parallel-Programmierung mit bekannten Mitteln
  3. Linux bietet SMP
  4. Steuerungsparallele Programmierung

Jetzt kostenfreie Newsletter bestellen!