[ < ] [ globale Übersicht ] [ Kapitelübersicht ] [ Stichwortsuche ] [ > ]

5.1 Qualität numerischer Programme

In diesem Abschnitt sollen Beurteilungskriterien für numerische Programme vorgestellt werden.


5.1.1 Zuverlässigkeit

Je mehr man von einem Programm weiß, je genauer dessen Aufgaben spezifiziert sind, desto genauer läßt sich die Zuverlässigkeit bestimmen. Dabei kennzeichnet sie den Grad der Wahrscheinlichkeit, mit dem das Programm seine Funktionen erfüllt.

Die Zuverlässigkeit machen Korrektheit, Robustheit, Genauigkeit, Autarkie und Konsistenz aus.


Korrektheit

Die klassische Definition eines korrekten Programmes ist folgende: Ein Programm ist dann korrekt, wenn es für alle Eingabedaten aus seinem Spezifikationsbereich richtige Ausgabedaten erzeugt. D.h. es müssen auch alle erlaubten Fehlerfälle - z.B. Fehlbedienung oder Tippfehler in Eingabedaten - richtig abgearbeitet werden. Auf numerische Programme ist diese Definition aber nur bedingt anwendbar, da die Anforderungen, Vorstellungen und Wünsche der eigentlichen Anwender immer weniger berücksichtigt werden, desto genauer und schärfer ein Programm spezifiziert (vorgegeben) wird. Dazu ein Beispiel:

Beispiel - Lineare Gleichungssysteme: Für ein Programm, das die Aufgabe hat, lineare Gleichungssysteme mittels Eliminationsalgorithmus ohne zusätzliche Vereinfachungsstrategien (Pivotstrategie, Skalierung, ...) zu lösen, kann ein formaler Korrektheitsbeweis geführt werden, d.h. nachgewiesen werden, daß es nur "richtige" Resultate liefert. Dieses Programm kann aber unter ungünstigen Aufgabenstellungen Ergebnisse (Ergebnisvektoren) liefern, die nicht einmal in einer einzigen Dezimalstelle mit der exakten Lösung übereinstimmen. Obwohl das Programm korrekt gerechnet und richtige Algorithmen eingesetzt hat, können z.B. Rechen- oder Datenfehler dieses Versagen hervorgerufen haben. Für den Anwender sind die Resultate unbrauchbar.

Diesem Beispiel kann man entnehmen, daß man bei der Entwicklung numerischer Programme auch auf die Eigenheiten von Rechnenwerken und Maschinenarithmetik Rücksicht nehmen muß, und anwendungsorientierte Anforderungsdefinitionen beachtet werden müssen. Ein dahingehend großes Problem ist der Übergang von kontinuierlichen mathematischen Modellen (analog) zu diskreten Modellen (digital), die in Computern bearbeitet werden können. Da in der EDV nicht unendlich viele Zustände repräsentiert werden können, muß es zwangsweise zu Ergebnisverfälschungen kommen.

Beispiel - Numerische Integration: Programme, die Funktionen integrieren sollen, beruhen auf dem Prinzip der Abtastung (sampling). Dabei wird der Integrand an endlich vielen Stellen abgetastet und die erhaltenen Werte zur eigentlichen Berechnung herbeigezogen. Diese Stellen werden entweder fix festgelegt (z.B.: alle 0.02 Einheiten) oder durch Hilfsfunktionen an das jeweilige Problem angepaßt, um z.B. in der Umgebung einer steilen Stelle oder einer Sprungstelle höhere Dichten zu erreichen. In jedem Fall wird ein erster Näherungswert und eine dazugehörige Fehlerschätzung auf Grund einer endlichen Stützstellenmenge bestimmt, die fester Bestandteil des Algorithmus ist. Wendet man das Integrationsprogamm auf

P_{2N}(x):=c\prod_{i=1}^N (x-x_i)^2

mit

c \neq 0

als Integrandenfunktion an, so geschieht folgendes: Das Polynom P wird an den Abtastpunkten x1,..,xN ausgewertet. Dort liegen aber deren Nullstellen, was das Programm zu der Annahme bringt, daß, wenn an all den ausgewerteten Stellen der Wert der Funktion Null ist, so muß es sich um die Nullfunktion handeln, und liefert mit der Fehlerschätzung Null das Ergebnis Null. Der tatsächliche Fehler des Ergebnisses kann somit beliebig groß werden, abhängig von der Wahl von c.

Bei diesem und ähnlichen Fällen müssen Einschränkungen der zulässigen Eingabedaten gemacht werden, um wenigstens in einem gewissen Bereich für volle Funktionalität garantieren zu können.

Beispiel - Numerische Integration: Wird vorausgesetzt, daß (je nach Integrationsformel) nur j-mal stetig differenzierbare Integrandenfunktionen f im Intervall [a,b] eingegeben werden können und daß der Wert einer Schranke Mj für die j-te Ableitung des Integranden

\vert f^{(j)}(x) \vert \leq M_j, x \in [a,b],

als Eingangsparameter an das Programm zu übergeben ist, dann ist es möglich, ein Programm zu entwickeln, das Resultate liefert, die

\vert \int_a^b f(x) dx - I_{approx} \vert \leq e_{abs}

garantiert einhalten (selbstverständlich nur dann, wenn man auch die Einflüsse der Maschinenarithmetik berücksichtigt).

Solche Einschränkungen, wie schon weiter oben erwähnt, sind aber selten im Sinne der Anwender, und größere Schwierigkeiten bereiten, als die ursprüngliche Integrationsaufgabe. Im Normalfall wird auf die Angabe einer Schranke durch den Benutzer verzichtet. Dann kann das Programm aber nicht mehr Gegenstand von problemrelevanten Korrektheitsbetrachtungen sein, und man muß sich mit Plausibilitätsbetrachtungen und Tests begnügen. D.h., man sollte sich als Anwender von numerischer Software immer informieren (z.B. in der Dokumentation), was man von den Programmen wirklich erwarten darf.


Robustheit

Die Robustheit definiert den Grad eines Programmes, mit dem es Fehler bei Eingangsdaten / Abläufen erkennt, für den Benutzer verständlich reagiert, aber trotzdem seine Funktionsfähigkeit wahrt. Ein Programm gilt als maximal robust, wenn es keine Möglichkeit einer Eingabe gibt, die es zu einer Fehlreaktionen zwingt oder sogar abstürzen läßt.
Bei numerischen Programmen liegt die Schwierigkeit der Anwendung des Robustheitsbegriffs darin, festzulegen, welche Eingabedaten als falsch oder nicht erlaubt einzustufen sind.

Beispiel - Numerische Integration: Selbst bei Vernachlässigung von Rundungsfehlern können bei Programmen zur numerischen Integration keine Garantien für Polynome beliebigen Grades gemacht werden. Es können nur eingeschränkte Zusicherungen bez. Grad oder speziellen Beschränkungen der Ableitung gemacht werden. Aufgrund von Dokumentationsmängel werden solche Programme oft als "universell anwendbar" eingestuft.
Da auf Grund des Abtastprinzips ein Computer eine Funktion nur auf endlich vielen Stellen untersuchen kann, ist es möglich, daß es dadurch zu einer Fehleinschätzung von Funktionen kommt. So kann es z.B. keinen Algorithmus geben, der über die Erfülltheit von Ableitungsschranken entscheidet, da dieser sich auf alle Punkte des Integrationsbereiches bezieht, und nicht nur auf endlich viele.

Beispiel - euklidische Vektorlänge: Gegeben sei folgendes Problem: Die Berechnung der euklidischen Länge eines Vektors

\Vert v \Vert _2 := \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2}

Das Unterprogramm BLAS/snrm2 als auch das Programm x2norm lösen diese Aufgabe korrekt und ohne Exponentenüberlauf, wenn das Resultat im Maschinenzahlenbereich liegt. Das ist aber keinesfalls selbstverständlich, wie der folgende Codeabschnitt zeigt:


   summe = 0. 
   DO i = 1, n 
      summe = summe + v(i)**2 
   END DO 
   norm_2 = SQRT(summe) 

Hier kann es auch zu einem Exponentenüberlauf oder -unterlauf bei Zwischenergebnissen kommen (nämlich bei der Variable summe), obwohl das Ergebnis (norm_2) durch die Wurzelfunktion SQRT eigentlich im Bereich der normalisierten Maschinenzahlen liegt.

Um optimale Robustheit zu besitzen, müßte ein Programm bei Daten, die zu einem Resultat außerhalb des Bereiches der Maschinenzahlen führen, nicht abbricht, sondern den Benutzer über diese Situation informiert.

Ein viel größeres Problem als ein Exponentenüberlauf (overflow, die Über- bzw. Unterschreitung der maximal darstellbaren positiven bzw. negativen Zahl), der im allgemeinen mit einem unfreiwilligen Programmabbruch endet, ist der Exponentenunterlauf (underflow). Hier wird ein Ergebnis zu klein, um noch darstellbar zu sein. Dieser Wert, der nahe bei Null liegt, wird dann stillschweigend auf Null gesetzt. Im allgemeinen kann man aber schwer abfragen, ob ein Ergebnis Null oder "fast Null" war. Robuste Software sollte möglichst frei von underflows sein.


Genauigkeit

Ein Programm gilt dann als genau, wenn es Ergebnisse liefert, die mit den exakten Resultaten übereinstimmen. Bei numerischen Programmen gilt der höchste Genauigkeitsgrad dann als erreicht, wenn das Resultat des Programmes mit der durch Rundung auf die Maschinenzahlen abgebildete exakte Lösung übereinstimmt. Diesem Ideal können aber nur Programme entsprechen, die bestimmte, wohldefinierte Problemklassen behandeln und sich auf spezielle Maschinenarithmetiken stützen.

Beispiel - ACRITH-XSC: Gängige Arithmetiken (z.B. die IEC/IEEE-Arithmetik) gestatten es nicht, Software mit maximaler Genauigkeit zu schreiben. Auf einigen IBM-Rechnern (und kompatiblen) ist deshalb eine Spezialarithmetik verfügbar, die Entwicklung von Software ermöglicht, welche Lösungen mit dem jeweils (rechnerabhängigen) maximalen Genauigkeitsgrad liefert.

Beispiel - Standardfunktionen: Die im allgemeinen als Standardfunktionen bezeichneten Funktionen sin, cos, exp, log etc. werden von Programmiersprachen in Form von Unterprogrammen, die meist auch mit SIN, COS, EXP, LOG, etc. bezeichnet werden, angeboten. Die Algorithmen, die diesen Unterprogrammen zugrunde liegen, bleiben aber im allgemeinen für den Benutzer verborgen und werden in den Dokumentationen auch selten erwähnt. Numerische Verfahren versuchen nun, die maximal erreichbare Genauigkeit zu erzielen. Dabei wird für einfach genaue Ergebnisse intern mit doppelter Genauigkeit gerechnet, für doppelt genaue Ergebnisse mit extended precision. In vielen Fällen läßt sich so für wichtige Argumentbereiche eine Genauigkeit garantieren, die nahe an der Maschinengenauigkeit liegt, aber es gibt auch Situationen, in denen die Genauigkeit deutlich schlechter ist. Sinusfunktionen werden oft in einem Bereich nahe Null durch eine rationale Funktion oder ein Polynom approximiert. Für die Bestimmung größerer Funktionswerte wird die Periodizität der Funktion ausgenützt, und die Werte auf ein kleines Intervall um Null zurückgeführt. Diese Reduktion, bei der man meist mehrfach PI/2 von der eigentlichen Zahl x abzieht, liefert ein reduziertes Argument

\overline x \in [-{\pi \over 4}, {\pi \over 4}]

Dabei ist die Auslöschung signifikanter Stellen bei der Reduktion mit größer werdendem x für Resultatungenauigkeiten verantwortlich. Davon kann man sich auf jedem Taschenrechner ein Bild machen, wenn für sin 710 anstatt des richtigen Ergebnisses 0.000060288706691585265933... nur 4 bis 5 der angezeigten 10 Stellen übereinstimmen.

Die Eigenschaften Robustheit und Genauigkeit können einander beeinflussen, wie man hier sieht. Allerdings ist ein Unterprogramm / eine Funktion, die ohne Rückmeldung nur 4 von 10 Stellen korrekt angibt, weder robust noch genau. Ein Unterprogramm, daß für einen möglichst großen Bereich maximale Genauigkeit liefert, und falls das nicht möglich ist, eine Warnung generiert, wäre in diesem Fall die beste Lösung.

Beispiel - Lineare Gleichungssysteme: Ist als Lösungsverfahren für lineare Gleichungssysteme der Gauß-Eliminationsalgorithmus vorgeschrieben (z.B. in der Spezifikation des Programmes), so können keine garantierte Genauigkeiten mehr sichergestellt werden. Der vom Gauß-Algorithmus gelieferte Lösungsvektor können nur mehr einer gesonderten Genauigkeitsuntersuchung unterzogen werden (z.B. LAPACK ermöglicht dies).

Oft wird aber bei numerischen Problemen eine Lösung mit maximaler Genauigkeit nicht angestrebt - es genügt die Sicherstellung der Korrektheit bei einer bestimmten Anzahl von Nachkommastellen. Konvergente Prozesse können dazu genutzt werden, vorgegebene Genauigkeitsschranken einzuhalten.

Beispiel - Archimedische Methode: Archimedes hat jene Methode entwickelt, die mit Hilfe von ein- und umgeschriebenen Polygonen die Länge (Umfang) eines Kreises zu bestimmen. Für die Länge einer Seite des einem Kreis mit dem Durchmesser 1 und dem Umfang PI eingeschriebenen regelmäßigen k-ecks gilt folgende Rekursion:

s_2k := sqrt{2 - sqrt{4-s_k^2}}

mit dem Startwert

s_6 := {1 \over 2}

Für den Umfang des regelmäßigen k-Ecks gilt die mathematische Konvergenzaussage:

U_k \rightarrow U

für

k \rightarrow \infty

Für jede Genauigkeitsforderung Epsilon gibt es somit ein K, für das der Verfahrensfehler kleiner Epsilon bleibt.

Aber selbst die korrekte Implementierung eines konvergenten Prozesses kann am Computer zu unerwarteten (falschen) Ergebnissen führen.

Beispiel - Archimedische Methode: Eine korrekte Implementierung der Rekursion aus dem obigen Beispiel liefert auf einer Workstation folgende Resultate:

k
6*21
6*22
6*29
6*217
6*218
6*219
6*220
k*s
3.105809
3.132629
3.141592
3.092329
3.000000
3.000000
0

Nach dem Erreichen einer recht guten Näherung von PI sinkt der Wert des Umfanges wieder, bis er letztendlich bei Null endet. Da man in diesem Fall die Lösung (PI) kennt, könnte man die Berechnung vorzeitig abbrechen. Wendet man allerdings die übliche Abbruchbedingung (das "Stehen" der Folge) an, so erhält man die völlig unbrauchbare Lösung 0.

An diesem Beispiel erkennt man die Problematik der Einschränkung auf Verfahrensfehlereffekte bei Korrekheitsuntersuchungen. Bei der Diskretisierung kontinuierlicher Informationen (z.B. der Integration von Polynomen) besteht keine Möglichkeit, verläßliche Genauigkeitsinformationen zu erhalten. U.U. kann das Ergebnis mit einem beliebigen Fehler behaftet sein.


Autarkie

Die Autarkie gibt jenen Grad eines Programmes bzw. eines Programmpaketes an, in dem es von anderen Programmen unabhängig ist. Ein autarkes (self-contained) Programm erfüllt seine Aufgaben selbständig und benötigt keine Hilfsprogramme bzw. Schnittstellen zur Eingabe, Bearbeitung, Prüfung und Ausgabe seiner Daten.

Beispiel - IMSL: Die IMSL-C-Math-Library und die IMSL-C-Stat-Libray, beides Teile der IMSL-Bibliothek können jedes für sich unabhängig an sie gestellte Probleme lösen. Sie sind somit autarke Softwareprodukte. Die einzelnen Bibliotheken jedoch enthalten nicht autarke Teilprogramme, die Hilfe von anderen Teilprogrammen benötigen.

Konsistenz

Software wird oft von vielen verschiedenen Personen entwickelt und gewartet. Um nun einheitliche Handhabung, Datenstrukturen, algorithmische Abläufe u.ä. zu gewähren, müssen Programmweite Richtlinien eingehalten werden. Die Konsistenz gibt den Grad der Verwirklichung dieser Richtlinien an. In diesen Punkt fallen auch die Einheitlichkeit bei Ein- und Ausgaben sowie in Formaten und Terminologien.

Beispiel - Lineare Algebra: LAPACK (Linear Algebra Package) und TEMPLATES wurden von großen Expertenteams entwickelt, die an mehreren - in Amerika und Europa verstreuten - Universitäten und Forschungsinstituten beschäftigt waren. Trotzdem besitzen diese Softwarepakete eine hohe Konsistenz, da bei der Entwicklung strenge Richtlinien und Spezifikationen vorgegeben waren.


5.1.2 Portabilität

Die Entwicklung von Software ist ein sehr zeitaufwendiges und kostspieliges Unterfangen. Darum ist es nur zu verständlich, daß Firmen und Organisationen, die viel in die Erstellung von Programmen / Programmpaketen investiert haben, diese möglichst lange nutzen wollen. Aber gerade in der EDV ist der Fortschritt in Hard- und Software enorm. Topaktuelle Geräte sind in wenigen Jahren (manchmal sogar nur Monaten) veraltet oder zu langsam. Bei einer Neuanschaffung möchte man darum alte, "selbstgestrickte" Programme weiterverwenden. In einigen Fällen will man Software aber einfach nur an Dritte weitergeben. Spätestens dann zeigt sich, wie portabel ein Programm wirklich ist.

Beispiel - UNIX: Das 1973 von D.M.Ritchie und K.Thompson entwickelte Betriebsystem UNIX war ursprünglich nur für ein Eigenbedarf eines Forschungszentrums (die Bell Laboratories von AT&T) entwickelt worden. Durch die sehr hohe Portabilität von unter UNIX geschriebener Software hat sich UNIX weit verbreitet, und hat sogar einen Einzug in die herkömmliche PC-Welt gefunden (LINUX).

Der relativ geringe Mehraufwand für eine portables Programm rechnet sich somit bei einem längeren Betrachtunszeitraum. Ein Konzept bei der Entwicklung portabler, aber effizienter Software ist die Trennung der laufzeitkritischen Teilalgorithmen (Unterprogramme, computational kernels) von der eigentlichen Implementierung in einer höheren Programmiersprache. Es können dann auch maschinenabhängige Rechenmodule entwickelt werden, die hinsichtlich der Laufzeit optimiert sind.

Beispiel - BLAS: Die Basic Linear Algebra Subroutines definieren elementare Algorithmen der numerischen Linearen Algebra und sind als Fortran-Programme zugänglich. Nun gibt es für die verschiedenen Computersysteme jeweils eigene, individuell optimierte Versionen. Damit entwickelte Programme sind jedoch portabel, da eine einheitliche Schnittstelle zu den Subroutinen besteht. Es muß lediglich die portable Fortran-Version durch die jeweilige Maschinenversion ausgetauscht werden. Das Softwareprodukt LAPACK wurde auf der Basis von BLAS entwickelt. Um eine optimale Effizienz zu gewährleisten, benötigt LAPACK deshalb nur eine möglichst effiziente Implementierung von BLAS auf dem eingesetzten Rechnersystem.

Da in der numerischen Datenverarbeitung häufig hohe Entwicklungskosten entstehen, bzw. es zu einer weiten Verbreitung existierender Software kommt, ist eine möglichst portable Programmierung anzustreben.

Beispiel - Schwach besetzte Systeme: Software zur Lösung von schwach besetzten linearen Gleichungssystemen wird nur an einigen Universitäten und Forschungszentren weltweit entwickelt (z.B. Yale oder Harwell). Die Resultate dieser Entwicklung werden aber weltweit genutzt. Deshalb muß diese Software möglichst portabel codiert sein.


Hardwareunabhängigkeit

Die Hardwareunabhängikeit eines Programmes gibt den Grad seiner Unabhängigkeit von spezifischen Hardwareeigenschaften und / oder -konfigurationen an (device independence).

Beispiel - Virtueller Speicher: Wenn ein Programm auf einer Plattform mit virtuellem (d.h. praktisch unbegrenztem) Speicher entwickelt wurde, ist es oft dahingehend spezifiziert und optimiert, diesen auch zu nützen. Soll nun dieses Programm auf einem kleineren System ohne virtuellen Speicher durchgeführt werden, kann es sein, daß der vorhandene Speicher nicht reicht. Das Programm muß umgeschrieben werden, was Zeit, Geld und Ressourcen kostet. Dies hätte vermieden werden können, wäre das Programm im vorhinein so konzipiert worden, daß es sich nicht auf beliebig viel Speicher "verläßt", sondern den tatsächlich vorhandenen effizient nutzt.

Beispiel - Java: Im Internet wird die Sprache Java immer populärer. Es handelt sich dabei um eine C-ähnliche, hardwareunabhängige Programmiersprache, deren Code in WWW-Seiten eingebettet werden kann. Verschiedenste Computersysteme können nun diesen Code interpretieren und ausführen. Diese Sprache garantiert einen sehr hohen Grad an Hardwareunabhängigkeit.


Softwareunabhängigkeit

Software kann aber nicht nur von Hardware (un-)abhängig sein, sondern auch von anderer Software, wie z.B. spezieller Anwendersoftware, Bibliotheken oder Betriebsystem(-funktionen). Die Softwareunabhängigkeit (software independence) beschreibt nun diesen Grad.

Beispiel - Spracherweiterungen: Einige Hersteller statten Programmiersprachen mit zusätzlichen Funktionen aus. Eine Verwendung dieser Funktionen kann sich aber als ungünstig erweisen, wenn Programme portiert werden, und am Zielsystem nur Compiler von anderen Firmen zur Verfügung stehen. Besonders hoch ist der Portieraufwand bei nicht normierten Programmiersprachen wie PL/I. Eine Ausführung solcher Programme auf nicht-IBM-Rechnern ist ohne umschreiben so gut wie unmöglich.


Maßnahmen zur Steigerung der Portabilität

Aus den oben genannten Faktoren ergeben sich sofort Strategien, wie man die Portabilität erhöhen kann:
Eine Steigerung der Portabilität läßt sich unter Umständen durch maschinenunabhängige Effizienzsteigerungen erzielen, da dadurch Programme auch auf weniger leistungsfähigen Systemen vernünftig eingesetzt werden können.


5.1.3 Effizienz

Programme und Programmpakete können vorhandene Ressourcen gut oder weniger gut beanspruchen b.z.w auslasten. Eine geringere CPU-Benutzung z.B., bedingt durch eine Überzahl von langsamen Speicherzugriffen können an sich gute und effiziente Algorithmen bremsen. Überlegungen zu diesem Thema werden unter dem Begriff Effizienz zusammengefaßt.

Grob kann man Effizienzüberlegungen in drei Kategorien einteilen:
Die ersten zwei Punkte sind nicht leicht voneinander trennbar - bessere Nutzung von (schnellen Zwischen-)Speichern verringert die zur Durchführung benötigte Zeit.

Obwohl die Übersetzungszeit im ersten Augenblick nebensächlich wirkt, kann sie vor allem bei großen Projekten hohe Ausmaße annehmen. Auch der (Hilfs-)Speicheraufwand darf nicht vernachlässigt werden. Je höher der vom Compiler geforderte Optimierungsgrad ist, desto mehr Ressourcen werden belegt. Der Mehraufwand bei aggressivem Optimieren kann auch bei Faktor 10 oder mehr liegen.

Abwägung zwischen Effizienz und Zuverlässigkeit

Bei einem Vergleich von Merkmalen der Zuverlässigkeit und der Effizienz gibt es einige Argumente zugunsten der Zuverlässigkeit:
Im Software-Engeneering, wo diese Argumente stark zählen, werden deshalb Software-Qualitätsicherungen und Softwareprüfungen hauptsächlich nach dem Qualitätsmerkmal Zuverlässigkeit ausgerichtet.


Notwendigkeit und Nebenwirkungen der Effizienz

Effizienz ist oft ein entscheidendes Merkmal bei numerischen Programmen. In Echtzeitsystemen gibt es "harte Zeitbedingungen", und Funktionen dürfen nur die Zeit benötigen, die sie auch haben. Uneffiziente (und damit langsame) Teile solcher Applikationen können das ganze System ins Wanken bringen. Bei interaktiven Programmen soll die Antwortzeit kurz gehalten werden, um den Anwender nicht lange warten zu lassen. Daher ist bei numerischen Programmbibliotheken neben der Zuverlässigkeit, der Benutzerfreundlichkeit und der Portabilität die Effizienz ein wichtiges Qualitätsmerkmal.

Beispiel - BLAS: In den Basic Linear Algebra Subroutines des Programmpaketes LAPACK werden Geschwindigkeitssteigerungen hauptsächlich durch Aufrollen von Schleifen erreicht.

In einer Studie über den Zusammenhang von Entwicklungskosten und Hardwareausnutzung wurden praktisch ausgeführte Projekte untersucht. Dabei zeigte sich, daß bei möglichst optimaler Nutzung der Ressourcen und Betriebsmittel der Entwicklunsaufwand sehr stark steigt. Es sind z.B. an einfachen Algorithmen wie dem Gauß-Algorithmus (Elimiationsalgorithmus), wenn diese für moderne Vektor- oder Parallelrechner codiert werden, viele Modifikationen notwendig. Auch spätere Wartungskosten erhöhen sich. Die Kosten für diesen hohen Aufwand tragen dann die einzelnen Anwender, da für diese die Aufteilung über Lizenzgebühren nicht (kaum) ins Gewicht fällt (z.B. bei IMSL- und NAG-Programmbibliotheken).

Adaptive Programme

Um eine maximale Portabilität zu gewährleisten müßten Programme überhaupt keine maschinenspezifische Teile enthalten. Um eine maximale Effizienz zu besitzen, müßte ein Programm möglichst alle Vorteile einer speziellen Rechnerumgebung machen. Diese zwei Attribute zu vereinen, ist eine schwere Aufgabe. Ein Lösungsansatz ist, den Programmen die Möglichkeit zu geben, ihre Rechnerumgebung festzustellen und entsprechend der vorhandenen Ressourcen und Möglichkeiten zu agieren. Die Informationsbeschaffung adaptiver Programme über das sie umgebende System kann z.B. mittels genormten Funktionen und Elementen der Programmiersprache geschehen. So ist es z.B. in ANSI C oder Fortran 90 möglich, Informationen über die Gleitpunktdarstellung und -arithmetik des jeweiligen Rechners während der Laufzeit zu erhalten. Dadurch kann ein Programm z.B. die Abbruchkriterien von iterativen Algorithmen anpassen.

Diese Art der Informationsbeschaffung dient als Grundlage für die Entwicklung portabler und effizienter Software, und spielt bei modernen Rechnerarchitekturen (Vektorrechner, Parallelrechner) eine fundamentale Rolle.


[ < ] [ globale Übersicht ] [ Kapitelübersicht ] [ Stichwortsuche ] [ > ]