Datenbusse
Die Ergebnisse der Leistungsmessungen (Abbildung 2 und 3) zeigen, dass die Bandbreite des Speicherbusses von den Kernen gemeinsam genutzt wird. Wenn die Kerne auf einem Datensatz arbeiten, der so groß ist, dass die Caches keine Wirkung haben, sinkt die Leistung auf 50 %, wenn beide Kerne aktiv sind. Der gleiche Effekt wurde auf dem PCI-Bus gemessen. Während eine Cache-Trefferrate von 0 % beim Speicherzugriff sehr unwahrscheinlich sein mag, ist sie auf dem PCI-Bus der Normalfall, da auf PCI-Geräte in der Regel mit deaktivierten Caches zugegriffen wird.
Gemeinsam genutzte E/A-Geräte
Die durch den gleichzeitigen Zugriff auf ein gemeinsam genutztes E/A-Gerät verursachte Leistungsminderung hängt hauptsächlich von dem Bus ab, der das Gerät mit dem Prozessor verbindet (z. B. der PCI-Bus), sowie von dem Gerät selbst. Ein Gerät, das nur eine Anfrage zur gleichen Zeit bearbeiten kann, kann eine zweite Anfrage für Hunderte von Mikrosekunden blockieren.
Gemeinsam genutzte Interrupts
Auf einer Multi-Core-Plattform wird ein Hardware-Interrupt in der Regel an einen Kern weitergeleitet. Wenn mehrere Geräte an eine Interrupt-Leitung angeschlossen sind und die Geräte nicht von demselben Kern bedient werden, muss der Kern, der den Interrupt empfängt, diesen Interrupt auch an den/die anderen Kern(e) weiterleiten und sie zwingen, den Interrupt-Status ihrer Geräte zu überprüfen. Gemeinsame Interrupts können zu erheblichen Interferenzen zwischen den Kernen führen und müssen durch ein geeignetes Plattformdesign vermieden werden.
Software-Störungskanäle
Eine der wichtigsten Komponenten eines IMA-Moduls ist die Kernsoftware einschließlich des Betriebssystems. Die Kernsoftware muss eine Ausführungsumgebung für die gehosteten Anwendungen bereitstellen, die einerseits die Plattformmerkmale vor den gehosteten Anwendungen verbirgt und andererseits die Nutzung der Plattformressourcen für alle Anwendungen streng kontrolliert. Während die meisten Hardware-Plattformen und Betriebssysteme auf eine optimierte durchschnittliche Rechenleistung ausgelegt sind, müssen die IMA-Module den Anwendungen eine hohe und konstante Rechenbandbreite gemäß dem vordefinierten Zeitplan zur Verfügung stellen. Die Systemsoftware muss eine unbeabsichtigte Kopplung zwischen den Partitionen aufgrund des Zugriffs auf gemeinsam genutzte Ressourcen verhindern und darf keine zusätzlichen Störungskanäle durch den gleichzeitigen Zugriff auf die Systemsoftware selbst einführen. Im Vergleich zu einem Single-Core-Design, bei dem sich die asynchrone Plattformnutzung mit Auswirkungen auf die laufende Anwendung hauptsächlich auf die Interrupt-Verarbeitung und von E/A-Geräten initiierte DMA-Transfers beschränkt, ist der asynchrone Zugriff auf Plattform- und Systemsoftware-Ressourcen der Normalfall auf Multi-Core-Plattformen.
Die Vielfalt der CPU- und Plattformarchitekturen und der funktionalen Anforderungen führt zu unterschiedlichen Konzepten der Multi-Core-Unterstützung in der Kernsoftwarekomponente. Für eine Dual-Core-CPU könnte ein angepasstes ARINC 653 Zeitpartitionierungskonzept angemessen sein, während bei einer CPU mit 32 oder mehr Kernen eine Zeitpartitionierung möglicherweise nicht mehr sinnvoll ist. Im Folgenden gehen wir von einem Systemsoftware-Design aus, das mit dem ARINC 653 Partitionierungskonzept kompatibel ist, aber wir nehmen an, dass bestimmte Partitionen möglicherweise mehrere Kerne nutzen müssen.
Software-Konzepte für Multi-Core-Plattformen
Die Interferenz zwischen Softwarekomponenten, die gleichzeitig auf verschiedenen Kernen laufen, hängt hauptsächlich von der Softwarearchitektur und der Art und Weise ab, wie die Software die Kerne nutzt. In den folgenden Abschnitten werden die verschiedenen Konzepte für die Verwendung von Multi-Core-Prozessoren und die damit verbundenen Interferenzprobleme erörtert.
Betriebssystem-Ebene
Auf der Ebene des Betriebssystems werden zwei Konzepte zur Nutzung mehrerer Prozessorkerne unterschieden:
Das Asymmetric Multi-Processing (AMP oder ASMP) und das Symmetric Multi-Processing (SMP).
Beim AMP-Konzept wird eine Multi-Core-Prozessorplattform ähnlich wie ein Multiprozessorsystem verwendet. Jeder Kern führt seine eigene, auf einen Kern bezogene Systemsoftwareschicht aus. Die Kerne sind über verschiedene Kommunikationskanäle lose gekoppelt, die auf Interrupts zwischen den Prozessoren, bestimmten gemeinsam genutzten Speicherbereichen oder anderen externen Geräten basieren können.
Die wichtigsten Vorteile des AMP-Konzepts sind:
- Die Systemsoftwareschicht muss nicht Multi-Core-fähig sein, was den Entwurf vereinfacht.
- Es gibt keine implizite Kopplung durch gemeinsam genutzte Daten und kritische Abschnitte innerhalb der Systemsoftwareschicht.
- Jeder Kern kann eine Systemsoftwareschicht ausführen, die für die auszuführende Aufgabe optimiert ist. Ein Beispiel hierfür ist eine Dual-Core-Plattform, bei der ein Kern für die E/A-Verarbeitung und Datenkonzentration zuständig ist, während auf dem anderen Kern ein ARINC-653-konformes Betriebssystem läuft, auf dem die Anwendungen laufen.
Die Nachteile des AMP-Ansatzes sind:
- Alle Systemsoftware-Instanzen müssen auf der höchsten für die Plattform geltenden Stufe zertifiziert sein, da sie vollen Zugriff auf privilegierte Prozessorregister und -befehle haben.
- Die Partitionierung der Plattformressourcen ist komplizierter, insbesondere wenn verschiedene Systemsoftwareschichten verwendet werden. Dies beschränkt den Einsatz des APM-Konzepts auf CPUs mit einer geringen Anzahl von Kernen.
- Die Synchronisierung zwischen Anwendungen, die auf verschiedenen Kernen laufen, ist komplexer.
- Der AMP-Ansatz unterstützt keine parallele Ausführung auf Anwendungsebene.
Interferenzen auf einer AMP-Plattform werden hauptsächlich durch gemeinsam genutzte Caches, Speicher- und E/A-Busse und den gleichzeitigen Zugriff auf gemeinsam genutzte Geräte verursacht. Interferenzen auf dem Speicherbus sind schwer zu vermeiden, während der Zugriff auf E/A-Geräte auf einen Kern beschränkt sein kann. Kohärenzprobleme beschränken sich auf einzelne Kommunikationspuffer, und die von der Systemsoftware verursachten Störungen beschränken sich auf gemeinsam genutzte Gerätehandles.
Beim SMP-Konzept wird eine Systemsoftwareinstanz zur Steuerung aller Kerne und Plattformressourcen verwendet. Das Betriebssystem bietet in der Regel Kommunikationsdienste zwischen und innerhalb von Partitionen, die die kernübergreifende Kommunikation transparent verwalten. Die Gerätetreiber sind für die Verwaltung des gleichzeitigen Zugriffs auf die Plattformressourcen zuständig.
Die Vorteile des SMP-Ansatzes sind:
- Es gibt nur eine Systemsoftwareinstanz, die für das Partitionierungskonzept verantwortlich ist, wodurch sich der Zertifizierungsaufwand auf ein Softwarepaket beschränkt.
- Es ist nur eine Plattformkonfigurationsschicht erforderlich.
- Die SMP-Systemsoftware kann die Ausführung kritischer Aufgaben vollständig isolieren, indem sie z. B. die gleichzeitige Ausführung von nicht vertrauenswürdigen Partitionen vorübergehend deaktiviert.
- SMP bietet viel mehr Flexibilität und ermöglicht einen besseren Lastausgleich als eine AMP-Konfiguration.
- Die parallele Ausführung auf Anwendungsebene kann unterstützt werden, wenn Interferenzen zwischen Kernen keine Rolle spielen, z. B. bei nicht sicherheitsrelevanten Partitionen.
Die Hauptnachteile des SMP-Ansatzes sind:
- Die Systemsoftwareschicht ist komplexer, da sie ihre internen Daten vor gleichzeitigem Zugriff schützen muss, ohne dass dies erhebliche Auswirkungen auf parallele Dienstanforderungen hat.
- Die internen Daten müssen sehr sorgfältig angeordnet werden, um False-Sharing-Effekte zu vermeiden.
- Aufgrund der gemeinsam genutzten Systemsoftwareschicht lässt sich eine implizite Kopplung nicht zusammenhängender Ausführungsthreads nicht vollständig vermeiden.
Im Vergleich zu einer AMP-Konfiguration fügt der SMP-Ansatz eine wichtige Quelle potenzieller Störungen hinzu, nämlich die gemeinsam genutzte Systemsoftwareschicht. Ein sorgfältiger Entwurf kann jedoch die Auswirkungen durch die Implementierung feinkörniger kritischer Abschnitte begrenzen. Die internen Daten der Systemsoftwareschicht müssen sorgfältig angeordnet werden, um eine unbeabsichtigte Kopplung aufgrund einer falschen gemeinsamen Nutzung zu vermeiden.
Parallele Ausführung auf Thread-Ebene
Parallele Ausführung auf Thread-Ebene bedeutet, dass der Programmierer eine Anwendung in mehrere Ausführungs-Threads unterteilt und diese Threads an einen Prozessorkern bindet. Die Threads arbeiten in der Regel mit denselben Daten, z. B. den Anwendungsdaten, BSS- und Heap-Segmenten. Alle Effekte, die im Zusammenhang mit gemeinsam genutzten Caches, Cache-Kohärenz (insbesondere False Sharing) und Bus-Sharing diskutiert werden, müssen berücksichtigt werden, um die Worst-Case-Leistung einer solchen Anwendung zu bestimmen. Durch die explizite Erstellung von Threads hat der Programmierer mehr Kontrolle über den gleichzeitigen Zugriff auf gemeinsam genutzte Ressourcen als im Falle der parallelen Ausführung auf Blockebene mit dem OpenMP-Ansatz. Interferenzen zwischen Threads der gleichen Partition können für die Anwendung selbst zu Zeitproblemen führen, haben aber an sich keine Auswirkungen auf die Partitionierung.
Parallele Ausführung auf Anweisungsebene
Bestimmte Teile eines logischen Ausführungs-Threads können von mehreren Prozessorkernen parallel ausgeführt werden, wenn die verarbeiteten Eingangs- und Ausgangsdaten unabhängig sind. Die OpenMP-Anwendungsprogrammschnittstelle [5] definiert Compilerdirektiven, die Codeabschnitte angeben, die parallel ausgeführt werden können. Die OpenMP-Implementierung verwendet das fork/join-Konzept, bei dem der Haupt-Thread eine bestimmte Anzahl von Worker-Threads zur Ausführung des als parallel gekennzeichneten Codeabschnitts abzweigt. Nach Abschluss des parallelen Blocks schließen sich die Worker-Threads wieder mit dem Haupt-Thread zusammen. Die Zuweisung der Codeanweisungen an die Worker-Threads erfolgt durch den Compiler. Die Überlegungen zu Interferenzen sind dieselben wie bei der parallelen Ausführung auf Thread-Ebene, aber das Risiko einer falschen Aufteilung kann aufgrund der reduzierten Datenmengen auf Block-Ebene sogar höher sein.
Ein SMP-Konzept für IMA
In den vorangegangenen Abschnitten haben wir verschiedene Konzepte für die Verwendung von Mehrkernprozessoren erörtert. Der AMP-Ansatz ist für spezialisierte Lösungen interessant, insbesondere wenn er auf einer Dual-Core-Plattform eingesetzt wird, bei der ein Kern vollständig für die E/A-Verarbeitung zuständig ist und auf dem anderen Kern die Anwendungssoftware läuft. Die durch den E/A-Prozessor verursachte Störung ist überschaubar, da er vollständig unter der Kontrolle der (vertrauenswürdigen) Plattformsoftware läuft. Dieser Ansatz scheint als erster Schritt in Richtung Multi-Core-IMA sinnvoll zu sein, bietet aber keine nennenswerte zusätzliche Verarbeitungsbandbreite für die Anwendungen.
Ein generischerer Ansatz ist die Verwendung eines SMP-Betriebssystems, da es mit einer zunehmenden Anzahl von CPU-Kernen besser skaliert und eine höhere Flexibilität bietet.
Wir gehen davon aus, dass künftige IMA-Plattformen neben den kritischen Anwendungen auch eine wachsende Zahl von Anwendungen mit hohen Leistungsanforderungen, aber geringerer Kritikalität beherbergen müssen. Diese Anwendungen müssen auch nicht unbedingt auf der ARINC 653 Intra-Partition-API basieren, sondern können Laufzeitumgebungen wie POSIX®, Java oder sogar Linux erfordern. Sie können auch Multiprocessing auf Anwendungsebene erfordern.
Aufgrund der potenziellen Interferenzen zwischen den Anwendungen scheint es nicht machbar zu sein, eine sicherheitskritische Anwendung gleichzeitig mit einer nicht vertrauenswürdigen Anwendung laufen zu lassen. Das Betriebssystem muss den exklusiven Zugang zur Plattform für die kritischsten Anwendungen unterstützen. Intra-Partition-Multiprocessing für sicherheitskritische Anwendungen scheint ebenfalls fragwürdig zu sein, da die Analyse der Ausführungszeit im schlimmsten Fall unmöglich werden könnte.
Wenn keine kritische Anwendung läuft, kann die Plattform zwischen den Partitionen geteilt werden oder alle Kerne können der anspruchsvollsten Anwendung zur Verfügung gestellt werden.
Das Betriebssystem PikeOS ist ein gutes Beispiel dafür, dass der Bedarf an Hochleistungsrechnern für weniger kritische Anwendungen und ein hohes Maß an Determinismus und Isolierung für hochkritische Anwendungen auf einer Multicore-Plattform realisiert werden kann.
PikeOS bietet ein ARINC 653-konformes Partitionierungsmodell, das zusätzlich zur ARINC 653 API die Ausführung verschiedener Laufzeitumgebungen und APIs wie POSIX®, ADA, Java oder sogar ein vollständig virtualisiertes Linux innerhalb einer Partition ermöglicht.
Der Scheduler führt einen gemeinsamen Major Time Frame (MAF) aus, der das Betriebssystem vollständig ARINC 653-konform hält. Die CPU-Kerne werden statisch den Ressourcenpartitionen zugewiesen, wobei eine Ressourcenpartition mehrere Kerne nutzen kann. Abbildung 5 zeigt eine mögliche Konfiguration des PikeOS-Partitions-Schedulers: