Die frühen Computer
Wenn Technikgeschichten erzählt werden, gibt es, wie ich in der Einleitung schon angedeutet habe, offenbar ein Bedürfnis, das erste Exemplar eines bestimmten Gerätes herauszufinden. Auch in der Welt der Computer und Rechenmaschinen ist dieser Wunsch nicht unbekannt. In einer Gesellschaft, die vom Wettbewerb gekennzeichnet ist, scheint es wichtig, herauszufinden, welcher Computer von allen der erste war. Leider ist diese Frage gar nicht ohne Weiteres zu beantworten, denn man müsste zunächst einmal wissen, was überhaupt ein Computer ist. Darauf, dass ein Computer etwas ist, mit dem man rechnen kann, kann man sich vielleicht noch recht schnell einigen. Diese Beschreibung gilt aber auch für einen Abakus, einen Rechenschieber oder eine alte mechanische Registrierkasse aus dem Museum. Diese Gegenstände und Geräte werden aber üblicherweise nicht Computer genannt. Welche Eigenschaften muss ein Gerät also haben, damit man es einen Computer nennen kann und mit ins Rennen um den ersten Computer schickt? Je nachdem, wie man diese Frage beantwortet, kann man ein anderes Gerät als den ersten Computer identifizieren. Es ist zum Beispiel durchaus verständlich, den amerikanischen ENIAC (Electronic Numerical Integrator and Computer) aus dem Jahr 1945 als ersten Computer anzusehen. Der deutsche Ingenieur Konrad Zuse hat allerdings schon Jahre vorher automatische Rechengeräte konzipiert und gebaut. Wenn wir seine mechanischen Rechner außen vor lassen, die noch nicht wirklich einsatzfähig waren, kann man Zuses Computer Z3 von 1941 genauso gut als ersten Computer betrachten. Die Z3 war allerdings im Gegensatz zum ENIAC nicht elektronisch, sondern elektrisch bzw. elektromechanisch1, denn sie arbeitete mit Telefonrelais. Auch war die Z3 nicht als turingmächtige Maschine konzipiert. „Turingmächtig“ ist ein Begriff aus der theoretischen Informatik. Er bedeutet, vereinfacht gesagt, dass Sie mit dem Computer, wenn er denn nur über genug Speicher verfügt und Sie hinreichend Zeit haben, all das zu berechnen imstande sind, was Sie auch mit einem heutigen PC berechnen können. Mit Computern, die nicht turingmächtig sind, können Sie einige Berechnungen nicht durchführen. Die Zuse Z3 hatte etwa keine bedingte Befehlsausführung. Sie konnten mit ihr also nichts automatisch berechnen, was einer Fallunterscheidung bedürfte.
Die Z3 war in gewisser Weise wirklich der erste, aber eben (nur) der erste elektromechanische, programmierbare, vollautomatische Computer, während der ENIAC auch der erste, aber eben der erste elektronische, universell programmierbare Computer war. Auch andere Rechengeräte kommen für das Rennen um den ersten Computer infrage, so etwa der britische Colossus von 1943, der wie der ENIAC mit Röhren arbeitete und somit elektronisch war. Es handelte sich bei dieser Maschine aber nicht um einen universellen Rechner, sondern um einen Spezialrechner zum Knacken verschlüsselter Textnachrichten. Er wurde im Zweiten Weltkrieg genutzt, um Nachrichten der deutschen Admiralität zu entschlüsseln. Seine Programmiermöglichkeiten waren sehr beschränkt. Dennoch war der Colossus der erste Computer, nämlich der erste elektronische, teilprogrammierbare, digitale Spezialrechner.
Welcher Computer nun, mit den jeweiligen Attributen versehen, als erster Computer beschrieben wird, hängt – absurderweise – oft davon ab, aus welchem Land derjenige kommt, der die Zuschreibung macht. In den USA wurde lange Zeit nur der ENIAC als erster Computer betrachtet, in Deutschland wurde eher die Zuse Z3 als erster Computer angesehen und in England feierte man seit dem Ende der Geheimhaltung über das Knacken der deutschen Codes während des Zweiten Weltkriegs den Colossus als den ersten Computer. Ich möchte in dieser Frage nicht den Schiedsrichter spielen und einen ersten Computer küren, denn letztlich ist es ziemlich belanglos, welchem Gerät Sie den Titel geben, und die offenbare Verbindung der Suche nach dem Ersten mit Nationalstolz macht mir die Frage gänzlich unsympathisch. Aus dem Wettstreit darum, wer nun der Erste war, können wir eine vielleicht versöhnliche Konsequenz ziehen: Ende der 1930er bis Anfang der 1940er Jahre wurden an mehreren Orten auf der Erde unabhängig voneinander Anstrengungen unternommen, vollautomatische, elektronische Rechenanlagen zu bauen. Der Zweite Weltkrieg spielte bei der Entwicklung zwar eine zentrale Rolle, doch offenbar war auch – unabhängig davon – die Zeit einfach reif für die Erfindung des Computers.
Programmierung durch Verkabelung
Wenn Sie einmal etwas über die Bedienung früher Computer gesehen oder gelesen haben, haben Sie vielleicht ein Bild des amerikanischen ENIAC gesehen. Der Rechner wurde von 1943 bis 1945 für das amerikanische Militär gebaut und unter anderem dafür eingesetzt, komplexe Berechnungen für ballistische Flugbahnen durchzuführen. Der Rechner war dreißig Tonnen schwer, füllte eine ganze Halle und hatte eine Leistungsaufnahme von sage und schreibe 150 kW. Seine auffälligste Eigenheit war aber wohl, dass er per Verkabelung programmiert wurde und dass Eingabewerte für die Berechnungen unter anderem durch das Stellen von Drehschaltern eingegeben wurden.
Oben sehen Sie eine typische Ansicht des ENIAC. Auf der linken Seite sehen Sie das Programm in Form der Verkabelung der Module des Rechners. Auf der rechten Seite sind auf fahrbaren Gestellen angebrachte Anordnungen von Drehschaltern zu sehen, mit denen Zahlenwerte eingestellt werden konnten. Programmieren bedeutete beim ENIAC in seiner ursprünglichen, hier abgebildeten Konfiguration, etwas ganz anderes, als das, was man sich heute darunter vorstellt. Selbst das „Programm“ war beim ENIAC überhaupt nicht mit dem zu vergleichen, was später als Programm bezeichnet wurde und auch heute noch so bezeichnet wird. Der ENIAC war nur Hardware und auch das Programm war Teil dieser Hardware. Ohne die gesteckten Kabel war der ENIAC einfach nur eine Sammlung von Modulen wie etwa Akkumulatoren (Addierern), Multiplikatoren, Dividierern, Einstellfeldern sowie Druckern, Lochkartenlesern und entsprechenden Stanzern für die Ein- und Ausgabe. Die Verbindungen zwischen den Modulen bildeten das Programm. Den ENIAC zu programmieren, bedeutete, die Module entsprechend dem, was man berechnen wollte, miteinander zu verbinden. Heutzutage wird unter einem Programm im Allgemeinen eine Folge von Anweisungen verstanden, die dazu dienen, den Computer zu steuern. Dabei wird das Programm vom Computer Anweisung für Anweisung verarbeitet. Beim ENIAC konnte man das so nicht sagen. Der Rechner verarbeitete das Programm nicht und das Programm steuerte den Rechner auch nicht, sondern war ein Teil des Computers. Es handelte sich beim ENIAC um eine Art raumfüllenden Bausatz, aus dem sich der Programmierer für jedes zu lösende Problem einen neuen Computer zusammensetzte. Der ENIAC, der das Problem A lösen konnte, war, genau genommen, nicht der gleiche Computer, wie der, der das Problem B zu lösen imstande war.
Ein Programm für den ENIAC, also seine Verkabelung zum Lösen einer speziellen, meist komplexen, Rechenaufgabe, wurde auf Papier geplant. Oben ist ein Ausschnitt aus einem solchen „Panel Diagram“ abgebildet. Das Erstellen solcher Pläne dauerte oft Wochen und das anschließende Programmieren des Rechners durch das Stecken von Kabeln dann nochmals mehrere Tage. Die eigentliche Berechnung war dann, insofern der Rechner richtig funktionierte und bei der Planung und Verkabelung keine Fehler gemacht wurden, innerhalb weniger Minuten oder allenfalls Stunden erledigt.
Bilder des ENIAC werden gerne gezeigt, um darzustellen, wie weit die Computertechnik inzwischen fortgeschritten ist, schließlich sieht der ENIAC so schön primitiv und ungewöhnlich aus. Diese etwas verächtliche Sicht wird aber weder dem ENIAC noch den Computern danach wirklich gerecht. Die Art, wie der ENIAC programmiert wurde, hatte nämlich durchaus einen Vorteil, nämlich den der vergleichsweise hohen Rechengeschwindigkeit. Große Teile des Rechenprozesses liefen beim ENIAC parallel ab. Zudem konnte der Rechner sofort nach dem Start mit der Berechnung beginnen, denn das Programm lag ja in Form der Verkabelung und der Stellungen der Einstellglieder komplett vor. Es musste nicht erst langwierig eingelesen werden, wie es bei vielen Rechnern danach nötig war. Beides machte den ENIAC für die damalige Zeit extrem schnell. Diesem Vorteil stand allerdings die sehr schwierige Programmierung gegenüber. Es zeigte sich schnell, dass eine serialisierte und dadurch langsamere Arbeitsweise zugunsten einer besseren Programmierbarkeit gut in Kauf genommen werden konnte.
Programme als eigenständige Artefakte
Ein Programm des ENIAC war nicht im heutigen Sinne eine Abfolge von Anweisungen an den Computer, sondern der aktuelle Hardware-Zustand des Rechners, also die aktuellen Verkabelungen und Einstellungen. Es war kein eigenständiges physikalisches Artefakt, das dem Computer von außen zugeführt werden konnte. Den ENIAC neu zu programmieren, bedeutete, ihn komplett neu zu konfigurieren und zu verkabeln. Meines Wissens nach steht der ENIAC mit dieser Art und Weise der Programmierung ziemlich allein auf weiter Flur. Alle mir bekannten späteren, aber auch früheren Computer, wie die von Konrad Zuse, mussten zum Programmieren nicht komplett neu verkabelt werden. Programme lagen stattdessen als ein eigenes Artefakt vor, das dem Computer von außen als Eingabe zugeführt wurde. Die eigentliche Hardware des Computers blieb beim Programmwechsel unverändert. Als Grenzfall kann man hier einige IBM-Geräte ansehen, die durchaus über Programme auf Stecktafeln und damit als Verkabelung verfügten. IBM knüpfte hier an die Tradition seiner Maschinen an, mit denen Daten von Lochkarten tabelliert und verarbeitet werden konnten. Diese Geräte wurden durch Stecken von Kabeln konfiguriert. Kabelverbindungen legten etwa fest, welche Spalte eines Datensatzes addiert und was mit dem Ergebnis am Ende geschehen sollte. Frühe IBM-Rechner übernahmen diese Konfigurationsmöglichkeit zum Teil, waren aber nicht darauf festgelegt, dass Programme zwangsläufig auf diese Art und Weise spezifiziert werden mussten.
Betrachten wir einen Computer, der fast gleichzeitig mit dem ENIAC entwickelt wurde: Unten abgebildet ist der Rechner Z4 von Konrad Zuse. Die Entwicklung an diesem Rechner begann 1942 und war 1945 abgeschlossen. Vorher hatte Zuse den bereits kurz erwähnten Rechner Z3 gebaut, der 1941 fertiggestellt wurde. Die Z3 war aber für heutige Maßstäbe ziemlich eingeschränkt. Sie war, obwohl sie natürlich ziemlich groß war, eher vergleichbar mit einer Art automatisierbarem Taschenrechner als ein Computer im modernen Sinne, denn dem Rechner fehlte etwas ganz Grundlegendes, ohne das wir uns heute Computer und Programmierung gar nicht mehr vorstellen können. Der Befehlssatz der Z3 enthielt, wie oben schon angedeutet, keine bedingten Befehlsausführungen. Die Konsequenz: Die Programme der Z3, von Zuse „Rechenpläne“ genannt, konnten zwar die gleichen Rechenschritte für verschiedene Eingaben durchführen, aber nicht anhand von Zwischenergebnissen verschiedene Rechenwege wählen. Die Z4 war der Z3 von der grundsätzlichen Arbeitsweise her zwar sehr ähnlich, verfügte aber im Gegensatz zu ihrer Vorgängerin über ebendiese bedingten Befehlsausführungen.
Programme lagen bei Zuses Rechnern Z3 bis Z11 als Lochstreifen2 vor. Auf der Abbildung rechts ist ein kurzer Lochstreifen zu sehen. Lochstreifen dieser Art wurden bei Computern bis in die 1970er Jahre hinein als Eingabemedium genutzt. Es handelt sich um einen einfachen Papierstreifen. Auf diese Streifen wurden Reihen von Löchern gestanzt. Eine solche Reihe war jeweils eine binäre Codierung eines Zeichens oder einer Zahl. Binär bedeutet, dass es sich um eine Codierung mit zwei Zuständen handelt. Jede Zahl entspricht also einer Folge aus Ja und Nein, 1 und 0 oder hier Loch und Nicht-Loch. Typische Lochstreifen enthielten pro Zeile meist entweder 5 oder 8 Löcher, der Code entsprechend 5 oder 8 Bit.
Diese Lochstreifen wurden nicht für den Computer erfunden, sondern fanden schon lange vorher in der Nachrichtentechnik für Fernschreiber Verwendung. Ein Fernschreiber war im Prinzip nichts anderes als eine Schreibmaschine, die mit einer anderen Schreibmaschine – einem anderen Fernschreiber – verbunden werden konnte. Diese Verbindung konnte über explizite Telegrafenleitungen oder auch über eine Telefonleitung per Modem erfolgen. Sobald zwei Fernschreiber miteinander verbunden waren, erschien alles, was auf einem der Fernschreiber geschrieben wurde, auch auf dem anderen Gerät. Fernschreiber erlaubten also das simultane Übermitteln von Textnachrichten über große Entfernungen – also etwa das, was wir heute „Chatten“ nennen. Viele Fernschreibgeräte verfügten über Lochstreifenleser und Lochstreifenstanzer. War ein Stanzer beim Empfang einer Nachricht eingeschaltet, wurden die empfangenen und eingegebenen Zeichen nicht nur auf Papier gedruckt, sondern zusätzlich entsprechend codiert auf den Streifen gestanzt. Über einen Leser konnte ein Fernschreiber einen Lochstreifen elektronisch einlesen und verhielt sich dann so, als würden die codierten Zeichen gerade in diesem Moment eingetippt. Lochstreifen dienten also dazu, Texte zwischenzuspeichern, um sie mehrfach senden oder um einen von einer Gegenstelle empfangenen Text an eine andere Stelle weitergeben zu können. Fernschreiber werden uns im Kapitel Time-Sharing wieder begegnen. Im Moment reicht uns ihr Speichermedium, der Lochstreifen.
Zuse verwendete die Lochstreifen nicht zur Speicherung von natürlichsprachlichen Texten, sondern zur Speicherung eines „Rechenplans“, also dessen, was wir heute „Programm“ nennen würden. Ein Rechenplan bestand aus einer Reihe von recht simplen Befehlen, die dann, eventuell um Zahlenwerte angereichert, in Bit-Folgen umgewandelt auf dem Lochstreifen abgelegt waren. Ich möchte hier, was diese Befehle angeht, nicht zu sehr ins Detail gehen. Es reicht an dieser Stelle, wenn Sie wissen, dass die Befehle größtenteils aus einfachen Rechenoperationen, also Addieren, Subtrahieren, Multiplizieren, Dividieren, Wurzelziehen etc. bestanden. Hinzu kamen Befehle, um Zahlen im Speicher des Computers abzulegen oder aus dem Speicher zu laden. Der Computer verfügte über zwei sogenannte „Register“. Diese Register waren spezielle Speicher, die die Recheneinheit in direktem Zugriff hatte. Es standen also stets nur zwei Zahlen direkt für Berechnungen zur Verfügung. Brauchte man im Programmverlauf eine berechnete Zahl später erneut, musste man sie im Arbeitsspeicher ablegen und danach wieder in ein Register laden. Einer der wichtigsten Befehle im Befehlssatz des Z4 und seiner Nachfolger war die bedingte Befehlsausführung. Sie prüfte zum Beispiel, ob das aktuelle Zwischenergebnis in einem der Register größer als Null war. War dies der Fall, wurde der darauffolgende Befehl auf dem Lochstreifen ausgeführt, andernfalls wurde er ignoriert.
Zuses Rechner lasen das Programm von einem Lochstreifenleser Befehl für Befehl ein und führten es direkt aus. Die Z3 hatte nur einen derartigen Programmleser. Die Rechner ab der Z4 besaßen zwei Lochstreifenleser. Mittels eines speziellen Programmbefehls konnte ein Programm den Rechner dazu veranlassen, zwischen beiden Lochstreifenlesern umzuschalten. Das Hinzufügen des zweiten Lochstreifenlesers erlaubte es den Programmierern, sogenannte Schleifen zu programmieren. Schleifen sind eine sehr grundlegende Technik in der Programmierung. Man braucht sie immer dann, wenn man es mit einer großen Menge an Informationen, etwa einer Liste, zu tun hat, die abgearbeitet werden muss, oder allgemeiner, wenn man etwas so lange wiederholen muss, bis eine bestimmte Bedingung erfüllt ist. Das Programm muss in solchen Fällen einen ganzen Satz von Befehlen immer wieder durchführen, bis alle Daten verarbeitet sind oder die gewünschte Bedingung eingetreten ist. Den Ausdruck „Schleife“ konnte man bei der Z4 ziemlich wörtlich nehmen. Es wurde zum Erzeugen einer Schleife nämlich schlicht und ergreifend der in den zweiten Leser eingelegte Lochstreifen zu einer Schleife (bzw. eigentlich zu einem Ring) gebunden, sodass die gleichen Programmbefehle immer wieder von vorne gelesen wurden. Im vom ersten Lochstreifenleser gelesenen Programm konnte auf den zweiten Lochstreifenleser umgeschaltet werden. Auf diesem lief die Schleife ab. Damit der Rechner nun nicht bis in alle Ewigkeit diese Schleife abarbeitete, musste der in Schleife gebundene Programmteil einen bedingten Befehl enthalten, der irgendwann wieder auf den ersten Lochstreifen zurückschaltete oder den Programmablauf ganz beendete.
In der Architektur von Zuses Rechnern kann man die Charakteristik der Probleme erkennen, die Zuse lösen wollte. Zuse musste in seiner früheren Arbeit als Ingenieur im Bereich der Luftfahrt feststellen, dass immer gleiche Berechnungen immer wieder mit verschiedenen Werten durchgeführt werden mussten. Um diese mühselige und sich stets wiederholende Arbeit zu vereinfachen, wollte er eine Maschine entwickeln. Diese Grundcharakteristik – gleiche Rechenschritte, verschiedene Werte – spiegelte sich in der Nutzungsschnittstelle seiner Maschinen wider. An einem Zuse-Rechner, und hier unterscheiden sich die Rechner von Z3 bis Z11 überhaupt nicht, wurde stets grundsätzlich folgendermaßen gearbeitet:
- Die Lochstreifen, auf denen „der Rechenplan“ gespeichert war, wurden in die Lochstreifenleser eingefädelt.
- In den ersten Schritten des Rechenplanes wurden die initialen Werte per Tastatur „eingetastet“ und im Speicher abgelegt. Obwohl Zuses Rechner intern im Binärsystem arbeiteten, also mit 0 und 1, erfolgte die Eingabe im ingenieurfreundlichen Dezimalsystem. Die Konvertierung fand direkt nach der Eingabe statt.
- Waren alle Werte eingegeben, startete die eigentliche Berechnung. Der Rechner arbeitete nun die auf dem Lochstreifen gespeicherten Befehle einen nach dem anderen ab. Ausgaben des Programms erfolgten auf einer elektrischen Schreibmaschine.
Die Bedienung der Zuse Z4
Zuses Z4 war ein Rechner für Ingenieure. Diese Ingenieure saßen in der Regel selbst am Rechner und führten ihre Berechnungen durch. Wichtig ist dabei – wir werden gleich sehen, dass es auch ganz anders sein kann – dass Eingaben direkt am Rechner und direkt vor der Programmausführung gemacht wurden. Der Nutzer war bei der Rechnung anwesend und konnte den Programmablauf an der Steuerkonsole des Rechners kontrollieren, im Fehlerfall unterbrechen und Befehle manuell, vom Programm unabhängig, ausführen. Zahlen konnte die Z4 sowohl von einer Tastatur als auch von einem speziellen Lochstreifen – Zahlenstreifen genannt – einlesen, wobei gerade der Eingabe per Tastatur in Sachen Nutzungsschnittstelle viele Überlegungen zukamen. Eine Bedienungsanleitung des Rechners von 19533 etwa beschreibt:
Die eingetastete Zahl erscheint zur Kontrolle im Lampenfeld. Wenn
diese Kontrolle nicht stimmt: Taste "Irrtum" drücken und korrigieren.
Stimmt die Kontrolle: Taste "Fertig" drücken; dies bewirkt Überfüh-
rung der Zahl ins Rechenwerk und verunmöglicht jede Korrektur.
[...]
Die Aufforderung an die Bedienungsperson zum Eintasten (beim Rechnen
mit eingelegtem Rechnenplan) ist ein rotes Blinksignal, oder das
Aufleuchten einer Protokoll-Lampe.
Die besagte Protokoll-Lampe unterstützte den Ingenieur am Rechner bei der Eingabe vieler Werte für seine Berechnung. Sie war Teil des sogenannten Protokollfeldes, das darauf hinwies, welcher Wert zur Eingabe erwartetet wurde. Die Bedienungsanleitung beschreibt:
Das Prokollfeld dient zur Erleichterung des Eingebens vieler
Zahlen in bestimmter Anordnung (Matrix). Es ist jeweils die Zahl
des Protokolls einzugeben, unter der das Licht aufleuchtet. Dazu
müssen die Zahlen auf einem Protokollformular notiert werden, das
auf die Mattscheibe aufgelegt wird. Ein Protokollformular kann
natürlich nur zusammen mit einem bestimmten Rechenplan verwendet werden.
Für einen Rechenplan, bei dem eine ganze Reihe von Eingabewerten gemacht wurden, wurde also in gewisser Weise eine Art Eingabeformular mitgeliefert. Der Rechner konnte so jeweils anzeigen, welcher Wert nun eingegeben werden sollte.
Da die Eingabebefehle der Z4 die Recheneinheit anhielten und der Rechner außerdem über eine bedingte Befehlsausführung verfügte, wäre mit der Z4 grundsätzlich eine interaktive Arbeitsweise möglich gewesen, bei der die Nutzer während des Programmablaufs dazu aufgefordert worden wären, weitere Werte einzugeben, auf die das Programm dann hätte reagieren können. Diese Arbeitsweise war allerdings nicht üblich. Alle Erklärungen und Programmbeispiele für die Z4, die sich finden lassen, sehen vor, zu Beginn alle Daten eingeben zu lassen und diese danach ohne weitere Eingabenotwendigkeiten zu verarbeiten. Eine Programmieranleitung von Zuse aus dem Jahr 19454 empfiehlt etwa explizit:
Bei längeren Rechenplänen speichert man nicht nur diejenigen
Werte, deren Speicherung unbedingt nötig ist, um das Rechenwerk
frei zu machen, sondern es werden zunächst einmal sämtliche
Ausgangswerte ins Speicherwerk eingegeben und daraufhin die
eigentlich Rechnung durchgeführt. Dies hat folgende Vorteile:
1.) Der Aufbau des Rechenplanes ist einfacher.
2.) Bei der praktischen Durchrechnung erfolgt die Eintastung
der Ausgangswerte zügig am Anfang hintereinander. Darauf-
hin kann man die Maschine sich selbst überlassen.
3.) Die Werte können in der logischen Reihenfolge eingetastet
werden.
4.) Es kann nachträglich kontrolliert werden, ob die Maschine
mit den richtigen Werten gerechnet hat.
Dass eine interaktive Nutzung nicht das war, was Zuse für seinen Rechner im Sinne hatte, wurde im Übrigen schon durch die Aufteilung der Ein- und Ausgabgeräte (in der Anleitung Eingang und Ausgang genannt) klar. Protokollfelder, Tastatur und Zahlenfeld, also die Elemente für die komfortable Dateneingabe, befanden sich in unmittelbarer Nähe zueinander, die Schreibmaschine zur Ausgabe in einiger Entfernung davon. Zwar hatte diese Schreibmaschine auch eine Tastatur. Diese diente aber nicht der Eingabe für den Rechner.
Die angenehme Möglichkeit der Eingabe von Daten kann durchaus als ein Vorteil der Z4 angesehen werden. Ihr größter Nachteil, den sie mit allen frühen Rechnern von Zuse bis einschließlich Z11 teilte, war ihre geringe Verarbeitungsgeschwindigkeit. Die Computer arbeiteten mit Telefonrelais, die in ihrer Geschwindigkeit aufgrund der elektromechanischen Arbeitsweise natürlich eingeschränkt waren. Vor allem aber begrenzte die Art und Weise der Programmausführung, bei der das Programm während seiner Verarbeitung Befehl für Befehl vom Computer eingelesen wurde, die Geschwindigkeit. Zwar konnte man das Einlesen von Lochstreifen in gewissem Rahmen beschleunigen, doch hier gab es eine Obergrenze dessen, was möglich war, denn schließlich musste ja ein Papierstreifen von einer Rolle abgerollt werden. Das Papier durfte dabei nicht reißen oder zerknittern. Selbst wenn man hiervon einmal absah, gab es ein grundlegendes Problem: Ein Programm, das sequenziell eingelesen wurde, konnte natürlich auch nur sequenziell abgearbeitet werden. Es gab keine Möglichkeit, in einem Schritt an eine andere Stelle auf dem Lochstreifen zu springen und das Programm dort fortzusetzen. Ein Sprung an Stellen im Programm ist aber für komplexere Programme unbedingt notwendig. Zuses Rechner hatten, im Gegensatz zu den Computern, die ich Ihnen im weiteren Verlauf des Buches vorstellen werde, keinen Sprungbefehl, sondern einen Übersprungbefehl, der während des Einlesens des Programms alle Befehle überging, bis ein bestimmter Code eingelesen wurde. Durch die trickreiche Kombination dieses Übersprungbefehls mit der zuvor erläuterten Technik der Schleife war es so möglich, Programme mit mehreren Unterprogrammen zu erzeugen.
Ein Unterprogramm verwendet man in der Programmierung, wenn bestimmte Befehlsfolgen in einem Programm an verschiedenen Stellen immer wieder genutzt werden. Statt sie jedes mal zu wiederholen, lässt man den Computer an die Stelle im Programm springen, an der diese Befehle notiert sind, und springt hinterher wieder zurück ins eigentliche „Hauptprogramm“. Die Verwendung von Unterprogrammen macht die Programme nicht nur kürzer, sondern auch besser wartbar, denn Verbesserungen müssen nun nicht mehrfach sondern nur noch an einer Stelle vorgenommen werden. Da die Zuse-Rechner keinen Sprungbefehl hatten, war das Anspringen eines solchen Unterprogramms stets mit dem Überspringen vieler Programmbefehle verbunden, die dennoch eingelesen werden mussten5. Die Recheneinheit musste in dieser Zeit warten, bis es weitergehen konnte. Diese Arbeitsweise war weder schnell noch in der Programmierung besonders praktisch.
Stored Program – Das Programm im Computer
Eine viel schnellere Programmausführung und ein einfacheres Springen innerhalb eines Programms wurde dadurch möglich, dass das Programm während der Ausführung nicht Befehl für Befehl eingelesen wird, sondern bereits vollständig im Speicher vorliegt. Ein Rechner, der dies ermöglicht, wird „Stored Program Computer“ genannt. Im Deutschen wird hierfür oft der Begriff „speicherprogrammierbar“ verwendet, der aber, genau genommen, nicht ganz das Gleiche bezeichnet, legt er doch nicht nur nahe, dass sich das Programm im Speicher befindet, sondern auch, dass es im Speicher erstellt und bearbeitet werden kann. Auf diese Möglichkeit will ich an dieser Stelle aber (noch) nicht hinaus.
Einen Stored Program Computer zu betreiben, bedeutete natürlich, das Programm zunächst vollständig einlesen zu müssen. Wie lag so ein Programm vor? Was war das Speichermedium? Lochstreifen als Eingabemedium haben Sie schon kennengelernt. Auch ein Stored Program Computer konnte grundsätzlich mit Lochstreifen gefüttert werden. Der britische EDSAC von 1949, einer der ersten nennenswerten Computer, die nach dem Stored-Program-Konzept arbeiteten, verwendete zum Beispiel dieses einfache Eingabemedium – sowohl für das Programm als auch für die Daten.
Ein weiteres verbreitetes Speichermedium für Computer der damaligen Zeit waren Lochkarten. Die Geschichte der Lochkarten ist, wie auch schon die der Lochstreifen, weit älter als die Geschichte digitaler Computer. Die ersten Lochkarten wurden schon 1890 für die teilautomatische Auswertung der US-amerikanischen Volkszählung verwendet. Die Daten der einzelnen Bürger wurden dazu mit einem speziellen Gerät auf Karten gelocht. Ein Loch an einer bestimmten Stelle stand für das Geschlecht des Bürgers, ein anderes für die Religionszugehörigkeit, ein drittes gab den Beruf an. Die so erzeugten gelochten Karten konnten in Zählgeräte eingegeben werden. Je nach Lochung wurden dann Zähluhren einen Schritt weiter geschaltet. Herman Hollerith, der die Lochkartentechnik für die Volkszählung erfand, gründete Firmen auf Grundlage dieser Technologie. Seine Firmen bauten sowohl Eingabegeräte, um Lochkarten mit Daten zu füllen, als auch Verarbeitungsgeräte, die etwa die Daten eines Lochkartensatzes aggregieren und tabellarisch darstellen konnten. Holleriths Firmen gingen 1911 in der Computing Tabulating Recording Company auf, die in den 1920er Jahren in International Business Machines umbenannt wurde. Von dieser Firma IBM sollte in den folgenden Jahren der Computergeschichte noch häufig die Rede sein.
Die Standard-Lochkarten von IBM wurden nun auch für Computerprogramme und zur Dateneingabe in einen Computer verwendet. Das Prinzip einer Lochkarte war dem eines Lochstreifens dabei grundsätzlich sehr ähnlich. Ein Lochkartenleser las einen Lochkartenstapel Karte für Karte ein. Beschrieben werden konnten Lochkarten auf Lochkartenstanzern wie dem oben abgebildeten. Eine einzelne Karte entsprach in der Regel einem Datensatz oder, im Falle der Programmierung, einem Programmbefehl.
Nahezu alle Computer, die nach dem ENIAC gebaut und entwickelt wurden, waren Stored Program Computer. Auch der ENIAC wurde so umgebaut, dass man ihn als Stored Program Computer bezeichnen konnte6. Er lief dann zwar, je nach Berechnung, nur noch mit einem Sechstel der vorherigen Geschwindigkeit, da die Parallelität nicht mehr so gut ausgenutzt werden konnte, doch wurde dieser Performance-Verlust während der Berechnungen durch die erheblich einfachere Programmierbarkeit mehr als ausgeglichen. Als dritte Möglichkeit konnte der ENIAC nach dem Umbau auch das Programm direkt von Lochkarten einlesen. Das war natürlich noch langsamer und schränkte die Programmierbarkeit ein, da das Programm nicht im Speicher abgelegt, sondern Schritt für Schritt abgearbeitet wurde. Es hatte aber den Vorteil, dass keine Hardware-Änderungen mehr vorgenommen werden mussten und Programme leicht austauschbar und damit auch verbesserbar wurden.
Wie nutzt man einen Stored Program Computer wie den EDSAC?
Um einen typischen Stored Program Computer nutzen zu können, mussten sowohl das Programm als auch alle Eingabedaten vor dem Programmablauf vorliegen. Es mussten also zumindest alle Daten auf Lochkarten oder Lochstreifen vorbereitet werden. Wenn ein neues Programm geschrieben und ausgeführt werden musste, geschah dies in einem langwierigen Prozess:
- Das Programm wurde auf Papier in einem Code aufgeschrieben, der dem Befehlssatz des Computers entsprach. Diese Art des Programmcodes wird Assembler-Sprache7 genannt. In Assembler-Sprache entsprechen die Befehle direkt denen der Computerarchitektur. Befehle müssen aber nicht als Bitmuster oder Zahlen eingegeben werden, sondern werden durch leichter verstehbare Kürzel, sogenannte „Mnemonics“, notiert. Statt
01001011notiert man in Assembler-Sprache zum BeispielADDfür den Addierbefehl. Auch höhere Programmiersprachen waren möglich, kamen aber erst Anfang der 1960er Jahre auf. Mehr dazu daher im folgenden Kapitel. - Aus dem Assembler-Code musste das Programm in die Maschinensprache umcodiert werden. Aus Befehlen, die aus kurzen Buchstabenfolgen bestehen, etwa
JMPfür den Sprungbefehl, wurden so wieder Zahlenwerte, die der Computer direkt verarbeiten konnte. - Dieses Maschinensprachenprogramm musste nun auf Lochkarten oder Lochstreifen gestanzt werden.
- Die Lochkarten oder Lochstreifen mit dem Programm und allen Eingabedaten wurden einem Operator übergeben. Der Operator verwaltete eine Warteschlange von Programmen, die noch vor dem abgegebenen abzuarbeiten waren.
- Wenn das Programm an der Reihe war, ließ der Operator das Programm einlesen, legte die Eingabedaten in den Lochstreifen- oder Lochkartenleser und startete das Programm.
- Ausgaben des Programms wurden auf einem Drucker ausgeführt.
- Der Operator legte das Programm, die Eingabedaten und die ausgedruckten Ausgaben des Programms in einem Ausgabefach bereit, wo sie vom Nutzer abgeholt werden konnten.
Ganz schön kompliziert, etwas mit einem solchen Computer zu programmieren und das Programm dann auszuführen! Charakteristisch für die skizzierte Arbeitsweise war, dass Nutzer oder Programmierer – in den meisten Fällen wohl ein und dieselbe Person – mit dem Computer selbst gar nicht in Berührung kamen. Wie hoch, meinen Sie, war wohl die Wahrscheinlichkeit, dass ein so erstelltes Programm beim ersten Versuch komplett korrekt war? Es musste korrekt in Assembler-Sprache auf Papier programmiert, fehlerfrei in Maschinencode übertragen und dann ebenso richtig abgelocht worden sein. Ich möchte nicht für alle sprechen, aber ich zumindest würde sicher stets etliche Durchläufe brauchen, bis mein Programm korrekt wäre. Dieses Programmierproblem war nicht die einzige Konsequenz der Abgekoppeltheit zwischen der Bereitstellung von Programm und Daten und der Verarbeitung des Programms durch den Computer. Problematisch war auch die fehlende Interaktivität. Es war bei dieser Nutzungsweise gar nicht möglich, ein Programm zu schreiben, das dem Nutzer während des Programmablaufs eine Entscheidung abverlangte. Auch konnte der Nutzer nicht eingreifen, wenn das Programm „Amok lief“, also sinnlos lange rechnete, in eine Dauerschleife geriet oder massenweise unsinnige Ausgaben produzierte. Der Nutzer war ja überhaupt nicht anwesend. Alle Eventualitäten mussten vorher bedacht werden. Explizit formuliert wird dies in einem unter Informatikern recht berühmten Paper, das unter dem Namen John von Neumanns veröffentlicht wurde. In diesem „First Draft Report on the EDVAC“8 von 1945 wird ausgeführt:
An automatic computing system is a (usually highly composite) device, which can carry out instructions to perform calculations of a considerable order of complexity—e.g. to solve a non-linear partial differential equation in 2 or 3 independent variables numerically. The instructions which govern this operation must be given to the device in absolutely exhaustive detail. They include all numerical information which is required to solve the problem under consideration: Initial and boundary values of the dependent variables, values of fixed parameters (constants), tables of fixed functions which occur in the statement of the problem. These instructions must be given in some form which the device can sense: Punched into a system of punchcards or on teletype tape, magnetically impressed on steel tape or wire, photographically impressed on motion picture film, wired into one or more fixed or exchangeable plugboards—this list being by no means necessarily complete. All these procedures require the use of some code to express the logical and the algebraical definition of the problem under consideration, as well as the necessary numerical material.
Once these instructions are given to the device, it must be able to carry them out completely and without any need for further intelligent human intervention. At the end of the required operations the device must record the results again in one of the forms referred to above. The results are numerical data; they are a specified part of the numerical material produced by the device in the process of carrying out the instructions referred to above. (Hervorhebung nicht im Original)
Von Neumann beschreibt hier also einen Computer, bei dem Programme „without any need for further intelligent human intervention“ ablaufen. Nimmt man diese Definition so hin, kann man daraus ableiten, dass Computer für Nutzer und Programmierer überhaupt keine Nutzungsschnittstelle brauchen. Natürlich war auch von Neumann klar, dass tatsächliche Computer durchaus einige Bedienelemente brauchten, denn schließlich handelte es sich um Maschinen und Maschinen mussten gesteuert werden. Es brauchte zum Beispiel mindestens Knöpfe zum Ein- und Ausschalten, zum Starten und Unterbrechen der Operation und zum Einlesen des Programms und der Daten vom Lochkarten- oder Lochstreifenleser. Außerdem mussten sie natürlich auch über irgendeine Art Ausgabegerät, wie zum Beispiel einen Fernschreiber oder eine elektrische Schreibmaschine, verfügen. Diese Schnittstelle wäre das absolute Minimum. Die Kontrollpulte der Computer der damaligen Zeit hatten meist deutlich mehr Anzeigen und Knöpfe. Das reichte von der Anzeige der Aktivität einzelner Komponenten über die umfangreichen Darstellungen des Speicherinhalts bis hin zu Lampen zur Anzeige von Alarmzuständen. In der Tat gab es aber für das Programm selbst keinerlei Nutzungsschnittstelle. Das Programm lief, ganz von Neumann entsprechend, völlig ohne menschliche Intervention ab.
Diese Arbeitsweise mag Ihnen unpraktisch und unhaltbar vorkommen. Tatsächlich aber war diese Operationsart in vielen Bereichen bis weit in die 1970er Jahre der Standard. Die Trennung von Nutzer und Maschine wurde sogar, wie Sie im nächsten Kapitel sehen werden, noch weiter verstärkt.