(Quelle: pexels.com)

Oft hören, lernen und verwenden wir sogar Begriffe oder Phrasen, die wir nicht ganz verstehen. Ich finde, dass dies in der Softwareentwicklungs-Community recht häufig vorkommt, ob es sich nun um RESTful Web APIs, agile Methodik, maschinelles Lernen oder andere Begriffe handelt. Das ist nicht unbedingt etwas Schlechtes, aber es ist wichtig zu verstehen, wann man etwas wirklich kennt und wann man nur den Namen dafür kennt.

Für mich ist Systems Programming ein solcher Begriff. Ich möchte versuchen, in einfacher Sprache zu erklären, was damit gemeint ist.

Bevor wir verstehen können, was Systemprogrammierung bedeutet, müssen wir zunächst verstehen, was ein System ist. Software lässt sich in zwei Gruppen einteilen: Systemsoftware und Anwendungssoftware.

Systemsoftware ist Computersoftware, die eine Plattform für andere Software bietet. Beispiele für Systemsoftware sind Betriebssysteme, Software für die Computerwissenschaft, Spiel-Engines, Industrieautomatisierung und Software-as-a-Service-Anwendungen.
… Eine solche Software wird nicht als Systemsoftware betrachtet, wenn sie normalerweise deinstalliert werden kann, ohne die Funktion anderer Software zu beeinträchtigen.
– wikipedia.org

Systemsoftware ist eine Plattform, die aus Programmen und Diensten des Betriebssystems (OS) besteht, einschließlich Einstellungen und Präferenzen, Dateibibliotheken und Funktionen, die für Systemanwendungen verwendet werden. Systemsoftware umfasst auch Gerätetreiber, die grundlegende Computerhardware und Peripheriegeräte steuern.
– techopedia.com

Systemsoftware bezieht sich auf die Dateien und Programme, aus denen das Betriebssystem Ihres Computers besteht. Zu den Systemdateien gehören Funktionsbibliotheken, Systemdienste, Treiber für Drucker und andere Hardware, Systemeinstellungen und andere Konfigurationsdateien. Zu den Programmen, die Teil der Systemsoftware sind, gehören Assembler, Compiler, Dateiverwaltungstools, Systemdienstprogramme und Debugger.
– techterms.com

Die Wikipedia-Definition ist sehr vage, was als Systemsoftware gilt, solange sie Dienste für andere Anwendungen bereitstellt. Die beiden anderen Definitionen konzentrieren sich jedoch ausschließlich auf das Betriebssystem – Treiber, Kernel, Bibliotheken und Funktionen (man denke an Kernel/Libc-Header-Dateien und gemeinsam genutzte Objekte). Dies impliziert eine enge Beziehung zur Hardware. Wenn wir uns einen anderen Wikipedia-Artikel über Systemprogrammierung ansehen, sehen wir:

Systemprogrammierung erfordert ein hohes Maß an Hardware-Bewusstsein.

Der Artikel deutet weiter an, dass ein Kernstück der Systemprogrammierung darin besteht, dass die Dinge sehr schnell sein müssen. Das ist der Grund, warum wir viel über die Hardware wissen müssen. Es macht auch Sinn, dass Geschwindigkeit (Leistung) ein Kernbestandteil der Systemprogrammierung ist, wenn es sich um eine Plattform für andere Software handelt.

Wenn der zentralste Teil Ihrer Anwendung (die Systemsoftware-„Plattform“) langsam ist, dann ist die gesamte Anwendung langsam. Für viele Anwendungen, besonders im großen Maßstab, wäre dies ein entscheidender Faktor.

Systemsoftware in Kürze

Die obigen Zitate und andere Quellen haben mich zu den folgenden Kriterien für die Definition von Systemsoftware geführt:

  • Bietet eine Plattform für andere Software, auf der sie aufgebaut werden kann.
  • Stellt eine direkte oder enge Schnittstelle zur Computer-Hardware her, um die notwendige Leistung zu erzielen und Abstraktionen (als Teil der Plattform) darzustellen.

Was ist Systemsoftware und was nicht

Beispiele dafür, was Systemsoftware ist:

  • OS Kernels
  • Treiber
  • Bare Metal Hypervisors (z.g. Hyper-V und VM Ware ESXi)
  • Compiler (die native Binaries erzeugen) und Debugger

Beispiele dafür, was keine Systemsoftware ist:

  • GUI-Chat-Anwendung (Slack, Discord usw.)
  • Webbasierte JavaScript-Anwendung
  • Web-Service-API

Sie werden feststellen, dass Web-Service-APIs zwar einen Dienst für andere Software bereitstellen, aber (in der Regel) nicht mit der Hardware interagieren, um Abstraktionen über sie zu erstellen. Es gibt jedoch Anwendungen, die in eine mittlere Grauzone fallen. Dazu gehören Hochleistungscomputeranwendungen und eingebettete Software.

Hochleistungscomputeranwendungen (HPC), wie der Echtzeithandel an der Börse, stellen in der Regel keine Plattform zur Verfügung, aber es ist üblich, dass sie Code schreiben, der direkt mit der Hardware verbunden ist. Ein Beispiel wäre die Umgehung des vom Kernel angebotenen Netzwerkstacks und die Implementierung eines eigenen Netzwerkstacks, der direkt mit der/den Netzwerkkarte(n) kommuniziert. Auf diese Weise zeigt sich, dass HPC-Software viele Ähnlichkeiten mit Systemsoftware aufweist, da sie direkt mit der Hardware interagiert, um die erforderliche Leistungssteigerung zu erzielen.

Die Entwicklung von eingebetteter Software weist ebenfalls viele Ähnlichkeiten mit Systemsoftware auf, da Code geschrieben wird, um direkt mit der Hardware zu interagieren. Allerdings werden alle bereitgestellten Abstraktionen typischerweise von derselben Software genutzt und können nicht als Plattform betrachtet werden.

Es ist wichtig, Anwendungen zu erwähnen, die Ähnlichkeiten mit unserer Definition von Systemsoftware aufweisen, da Sie diese Anwendungen/Arbeitsplätze wahrscheinlich mit diesen Begriffen beschrieben sehen (Systemsoftware, Systemingenieure usw.).)

Systemprogrammierung (+ Sprachen)

(Photo by Roman Spiridonov on Unsplash)

Nachdem wir Systeme definiert haben, können wir nun Systemprogrammierung als den Akt der Erstellung von Systemsoftware unter Verwendung von Systemprogrammiersprachen definieren. Einfach genug, nicht wahr?

Nun, eines haben wir übersprungen: Sprachen. Die Leute reden oft über Systemprogrammiersprachen in einer Art und Weise wie „X ist großartig, es ist schnell, kompiliert und eine Systemprogrammiersprache.“ Aber ist jeder auf der gleichen Seite, was eine Systemprogrammiersprache ist?

Angesichts unserer Definitionen von Systemen würde ich die Kriterien für eine Systemprogrammiersprache wie folgt definieren:

  • Kompiliert zu einer nativen Binärdatei
  • Kann ohne Abhängigkeiten von anderer Software (einschließlich eines Kernels) erstellt werden
  • Leistungsmerkmale, die mit anderen Systemprogrammiersprachen vergleichbar sind

Haftungsausschluss: Dies ist meine Definition. Da es keine festen Kriterien gibt, leite ich eine Definition von dem ab, was mir in dem Kontext, in dem ich Systemsoftware definiert habe, sinnvoll erscheint.

Kompilieren zu nativem Binärcode

Wenn eine Sprache nicht zu einer ausführbaren Datei kompiliert werden kann, die von der CPU direkt interpretiert werden kann, dann läuft sie per Definition auf einer Plattform (z.B. JVM, Ruby VM, Python VM, etc.). Es mag hier einige Argumente geben, aber der Einfachheit halber halte ich dies für ein geeignetes Kriterium.

Keine Abhängigkeiten

Das Argument ist ähnlich wie bei der Kompilierung zu einer nativen Binärdatei. Wenn die Sprache immer die Anwesenheit anderer Software erfordert, um ausgeführt zu werden, dann läuft sie auf einer Plattform. Ein Beispiel hierfür ist Go und die darin enthaltene Standardbibliothek. Sie benötigt die Unterstützung des Betriebssystems, um grundlegende Aktionen wie die Zuweisung von Speicher, das Erzeugen von Threads (für die Ausführung von Goroutines), den eingebauten Netzwerkpoller und andere Aktionen durchzuführen. Obwohl es möglich ist, diese Kernfunktionen neu zu implementieren, stellt dies ein Hindernis für die Verwendung in diesem Kontext dar, und man kann sich leicht vorstellen, warum nicht alle Sprachen, selbst diejenigen, die zu statischen Binärdateien kompiliert werden können, als Systemprogrammiersprachen gedacht sind.

Ähnliche Leistungsmerkmale

Dies ist ein bisschen ein Ausweg. Es soll aber sagen, dass es innerhalb des Systems von Sprachen, die typischerweise als Systemprogrammiersprachen klassifiziert werden, keine großen (Größenordnungen) Unterschiede in den Leistungsmerkmalen geben sollte. Mit Eigenschaften meine ich ausdrücklich die Ausführungsgeschwindigkeit und die Speichereffizienz.

Der goldene Standard für den Vergleich ist C und/oder C++, wie er oft in vergleichenden Benchmarks dargestellt wird, die die Ausführungsgeschwindigkeit in der Größenordnung messen, um die Sprachen langsamer sind als C/C++.

Naming a Few

Die Sprachen, die einem angesichts der obigen Definition sofort einfallen, sind C und C++. Aber es gibt auch neuere Sprachen wie Rust und Nim, die diese Nische ebenfalls ausfüllen. Tatsächlich gibt es bereits ein Betriebssystem, das komplett in Rust geschrieben wurde (RedoxOS) und einen Kernel in Nim (nimkernel).

Lassen Sie uns über Go sprechen

Vorhin habe ich angedeutet, dass Go nicht unbedingt in die Familie der „Systemprogrammiersprachen“ fällt. Aber so wie nicht alle Anwendungen in Anwendungssoftware und Systemsoftware eingeteilt werden können, gilt das auch für Sprachen.

Oft wird Go als Systemprogrammiersprache bezeichnet und sogar golang.org wird zitiert:

Go ist eine Allzwecksprache, die mit dem Ziel der Systemprogrammierung entwickelt wurde.

Aber selbst das ist keine direkte Behauptung, dass Go eine Systemprogrammiersprache ist, sondern nur, dass sie mit diesem Ziel entwickelt wurde. Ich finde, dass es eher in der Mitte liegt.

Go lässt sich zwar zu nativen Binärdateien kompilieren, enthält nützliche Low-Level-Konzepte (rohe/unsichere Zeiger, native Typen wie Bytes und int32 und Inline-Assembly-Unterstützung) und ist relativ leistungsfähig, hat aber noch einige Herausforderungen zu bewältigen. Go wird mit einer Laufzeit und einem Garbage Collector ausgeliefert.

Eine Laufzeit bedeutet, dass ein Bootstrapping/Überschreiben der Laufzeit erforderlich ist, um in Umgebungen ohne Kernel zu laufen. Dies geht mehr in die interne Implementierung der Sprache, die sich in zukünftigen Versionen ändern könnte. Änderungen erfordern zusätzliche Bootstrapping-Arbeiten, wenn sich die Sprache weiterentwickelt.

Ein Garbage Collector (GC) bedeutet entweder, dass Go in den Anwendungsdomänen eingeschränkt ist, in denen es verwendet werden kann, oder dass der GC deaktiviert und durch manuelle Speicherverwaltung ersetzt werden muss. Für den Fall, dass der GC nicht ersetzt werden kann, würde die Echtzeit-Domäne (definiert durch Operationen, die innerhalb bestimmter Zeitgrenzen abgeschlossen werden müssen und/oder die Leistung wird in Nanosekunden gemessen) nicht in der Lage sein, nicht-deterministische Pausenzeiten eines GC zu riskieren.

Software für verteilte Systeme

Mit dem zunehmenden Gerede über verteilte Systeme und Anwendungen wie Kubernetes, die sehr populär werden, bekommen wir eine Menge neues Vokabular zu hören, das (wenn wir ehrlich sind) die meisten von uns nicht vollständig verstehen.

Bislang habe ich die Begriffe Systemprogrammierung und Systemingenieure in Zusammenhängen verwendet, in denen eigentlich verteilte Systemprogrammierung und verteilte Systemingenieure gemeint waren.

In diesem Beitrag haben wir Systemsoftware, Systemsprachen und Systemprogrammierung definiert. Wenn wir jedoch über verteilte Systeme sprechen, ändert sich die Bedeutung von System. Und obwohl ich hier nicht auf die spezifischen Unterschiede eingehen werde (vor allem, weil ich sie selbst noch besser verstehen muss), ist es wichtig, dass wir diese gedanklichen Unterscheidungen treffen und eine genauere Sprache verwenden, wenn wir können, um Verwirrung bei denjenigen zu vermeiden, die diesen Bereich noch lernen.

Articles

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.