Je weniger Informationen vom Speicher in den Prozessor geladen werden müssen, desto schneller kann ein Programm ausgeführt werden. Die natürliche Folge war, daß Befehlssätze mit sehr mächtigen Befehlen entwickelt wurden. Ein einziger dieser Befehle enthielt viele einzelne Arbeitsschritte und beschäftigte die CPU für ein Weilchen, wenn man schon die Menge der Daten so nehmen mußte, wie sie eben kamen. In der CPU selber wurden diese ,,komplexen Instruktionen`` in elementarere Anweisungen zerlegt, denen die harwaremäßig verdrahteten Funktionen des Prozessors entsprachen. Dieses Konzept nennt man CISC -- Complex Instruction Set Coding. Das Konzept behält erstmal seine Gültigkeit, wenn ein Cache, also ein schneller Speicher vorhanden ist: Hier hält das Laden der Instruktionen aus dem langsamen Speicher in den Befehlscache die Programmausführung auf.
Dieses Konzept birgt auch Probleme:
1. Ein Befehl muß erst dekodiert werden, und
das kostet Zeit, denn solange kann die CPU nichts tun.
2. Die komplexen Anweisungen werden auf komplexe
Hardware abgebildet, damit es sich lohnt, und die
muß dann erstmal als Transistorschaltung auf dem
Chip realisiert werden, mehr Instruktionen
kosten Entwicklungsarbeit und bedeuten höhere
Produktionskosten.
Als Alternative bot sich an, einfach die Masse der selten benötigten Befehle wegzulassen, und in der Hardware nur diejenigen zu implementieren, die auch häufig benutzt werden. Alle anderen Befehle werden dann vom Compiler aus diesen elementaren Befehlen aufgebaut, der stark reduzierte (RISC --- Reduced Instruction Set) Befehlssatz erfordert keine Dekodierung, und das spart (Entwicklungs-)Zeit bei den Prozessoren und Platz. Die Reduzierung von interner Prozessorverwaltung bei gleichzeitiger effizienterer Nutzung von vorhandenen funktionalen Einheiten ermöglicht es, den Chip mit weniger Transistorschaltungen zu bauen, der Entwicklungsaufwand wird drastisch reduziert.
Den Compiler liefert jetzt nicht mehr eine Softwarefirma, sondern wer den Chip gebaut hat, weiß auch am besten, was der Hobel so drauf hat, RISC-Compiler werden speziell auf die Prozessorarchitektur zugeschnitten. Vorbei sind die Zeiten, als die schnellsten Programme in Assembler geschrieben waren: Der Grund war einfach, daß die Compilerbauer keine Lust hatten, für jeden neuen Compiler die speziellen Features eines schon wieder anderen Prozessors zu implementieren. Wer sich die Mühe machte, die Eigenheiten des Prozessors per Assembler auszunutzen, konnte so Programme doch noch beschleunigen. Wer auf einer superskalaren RISC in Assembler programmiert, riskiert in der Regel, daß das Programm langsamer wird. Wahrscheinlich zwingt man dem Chip eine Befehlsreihenfolge auf (bezüglich Registerausnutzung, gleichzeitige Nutzung funktionaler Einheiten etc.), bei der sich verschiedene Einheiten gegenseitig blockieren, wo der der Compiler vielleicht schon weiß, daß man's besser machen kann. Codeumstellungen reichen auf RISC's in der Regel aus, um bei Verwendung eines effizienten Compilers das Maximum der Prozessorleistung zu erhalten.
Für schnelle Programmabarbeitung sind gute Compiler so wichtig wie gute Hardware, und die Programmiersprache ist da oft Nebensache.
Compilerbauer haben auch den Ruf von
Fortran77 als schneller Programmiersprache auf dem
Gewissen: Da Fortran für naturwissenschaftlich--technische
Anwendungen eingesetzt wird, und Mikros für derartige
Aufgaben in den ersten Jahren zu langsam waren, war die
Nachfrage nach Fortran-Compilern für solche Maschinen
entsprechend gering, verkauft und entwickelt wurden vor
allem Pascal-- und C--Compiler.
Beim Vergleich schnitt Fortran dann entsprechend schlecht
ab, was aber in erster Linie ein marktwirtschaftlicher
Effekt war. Genau umgekehrt verhält sich die Situtation
im High-End Bereich: C ist für Supercomputeranwendungen
noch wenig üblich, die Compiler sind jünger und
noch nicht so ausgereift wie
die Fortran-Compiler derselben Hardware--Plattform
und der generierte
Code ist dann auch langsamer. Pointer--Programmierung
reißt bei Gleitkommarechnungen
nichts raus, sondern verwirrt den Compiler eher bei
effizientem Memory-Management: Manche Compiler
möchten nämlich selber gern herumpointern,
aber man muß ihnen eine Chance geben.
Auf den japanischen
Vektorrechnern, wird die Vektorisierung von
C-Programmen völlig boykottiert,
und das sind immerhin die schnellsten
Monoprozessoren der Welt. Der Grund ist, daß die
Vektorisierung voraussehbare Speicherzugriffe erfordert--
bei indirekte Addressierung (Pointer) ist dies in der
Regel nicht mehr möglich.
In--core und Out-of-Core
CISC--Prozessoren zerstören häufig den Inhalt
der Speicherzellen, auf die sie zugreifen, RISC's
lassen ihn unversehrt. Dadurch gibt es auf
den beiden Rechnertypen verschiedene
Programmierstrategien:
CISC/Out of Core:
a1=5
a2=a1+c
a1=a2+d
RISC/In--Core:
a=5
a=a+c
a=a+d
Analog geschieht die optimierte Programmierung für Felder, wobei bei ungeschickter Programmierung optimierende Compiler den Code zum Teil umsetzen könnnen. Vorsicht bei alten Programmen aus der Großrechnerära: Sie sind in der Regel nach Out--Of--Core Techniken geschrieben und für moderne RISCs nicht ideal. Out--Of-Core erfordert mehr Eingabe/Ausgabeoperationen in und aus dem Cache, wofür Mainframe--CISCs eher geeignet sind als Workstation--RISCs.