Lade Inhalt...

Konzept zur Leistungsoptimierung von C++-Programmen

Diplomarbeit 2003 67 Seiten

Informatik - Allgemeines

Leseprobe

Inhaltsverzeichnis

1 Einleitung

2 Theoretische Grundlagen
2.1 Entwicklungsphasen eines Software-Projektes
2.1.1 Die Planungsphase
2.1.2 Die Definitionsphase
2.1.3 Die Entwurfsphase
2.1.4 Die Implementierungsphase
2.1.5 Die Abnahme- und Einführungsphase
2.1.6 Die Wartungs- und Pflegephase
2.2 Software-Teststrategien
2.2.1 Dynamische Tests
2.2.1.1 Diversifizierende Tests
2.2.1.2 Systemtests
2.2.2 Statische Tests
2.3 Analyse von Algorithmen
2.3.1 Empirische Methode zur Analyse von Algorithmen
2.3.2 Mathematische Methode zur Analyse von Algorithmen
2.4 Bausteinbasierte Software-Entwicklung

3 „Leistungsoptimierung im Nachhinein“
3.1 Notwendigkeit einer Leistungsoptimierung
3.2 Gründe für eine „Leistungsoptimierung im Nachhinein“
3.2.1 Abschätzungsrisiken vermeiden
3.2.2 Rechengeschwindigkeit der Hardware nutzen
3.3 Verbesserung der „Leistungsoptimierung im Nachhinein“

4 Prozess zur „Leistungsoptimierung im Nachhinein“
4.1 Planungsphase
4.1.1 Funktionsanalyse durchführen
4.1.2 Leistungsziel festlegen
4.1.3 Lastenheft erstellen
4.1.4 Entwicklungsaufwand abschätzen
4.2 Definitionsphase
4.2.1 Produktumgebung festlegen
4.2.2 Anforderungen spezifizieren
4.2.3 Pflichtenheft erstellen
4.3 Vorbereitungsphase
4.3.1 Quellcode ermitteln
4.3.2 Testumgebung festlegen
4.3.3 Testdaten generieren
4.3.4 Regressionstest durchführen
4.3.5 Zeitmessmethode festlegen
4.3.6 Benchmark-Messung durchführen
4.4 Optimierungsphase
4.4.1 Performance-Analyse durchführen
4.4.1.1 Die Methode „Inspektion“
4.4.1.2 Die Methode „Mathematische Analyse“
4.4.1.3 Die Methode „Performance-Messung“
4.4.2 Optimierungen implementieren
4.4.3 Regressionstest durchführen
4.4.4 Ergebnisse vergleichen
4.4.5 Fehler korrigieren
4.4.6 Benchmark-Messung durchführen
4.4.7 Messergebnisse vergleichen
4.4.8 Abbruchkriterium prüfen
4.5 Abschlussphase
4.5.1 Hilfsfunktionen entfernen
4.5.2 Systemtest durchführen
4.5.3 Produkt freigeben

5 Konzept zur „Leistungsoptimierung im Nachhinein“
5.1 Grundidee
5.2 Grundprinzip eines Optimierungskataloges

6 Entwicklung eines Optimierungskataloges
6.1 Anforderungen an einen Optimierungskatalog
6.1.1 Geeignete Darstellungsform
6.1.2 Thematische Gliederung
6.1.3 Einheitliche Namenskonvention
6.1.4 Ausführliche Dokumentation
6.1.5 Versionisierung der Optimierungsbausteine
6.1.6 Erweiterbarkeit
6.2 Realisierung eines Optimierungskataloges
6.2.1 Produktbeschreibung
6.2.2 Dateiformate
6.2.3 Namenskonventionen
6.2.4 Optimierungsbausteine
6.2.5 Aufbau des Optimierungskataloges

7 Fallbeispiel: Einsatz des Optimierungskataloges
7.1 Aufgabenstellung
7.2 Projektdurchführung

8 Resümee
8.1 Rückblick
8.2 Ergebnisse
8.3 Konsequenzen
8.4 Ausblicke

Abkürzungsverzeichnis

Abbildung in dieser Leseprobe nicht enthalten

Tabellenverzeichnis

Tabelle 1: Übersicht von Systemtestmethoden

Tabelle 2: Mögliche Komplexitäten von Algorithmen

Tabelle 3: Prozess der „Leistungsoptimierung im Nachhinein“

Tabelle 4: Gliederungsschema für das Lastenheft

Tabelle 5: Einflussfaktoren bei der Aufwandsabschätzung

Tabelle 6: Angaben zur Produktumgebung

Tabelle 7: Methoden zur Quellcode-Ermittlung

Tabelle 8: Verwendete Dateiformate im Optimierungskatalog

Tabelle 9: Optimierungsbausteine vom Typ „Formular“

Tabelle 10: Optimierungsbausteine vom Typ „C++-Klasse“

Tabelle 11: Optimierungsbausteine vom Typ „Programm“

Tabelle 12: Einsatz des Optimierungskataloges in der Planungsphase

Tabelle 13: Einsatz des Optimierungskataloges in der Definitionsphase

Tabelle 14: Einsatz des Optimierungskataloges in der Vorbereitungsphase

Tabelle 15: Einsatz des Optimierungskataloges in der Optimierungsphase

Tabelle 16: Einsatz des Optimierungskataloges in der Abschlussphase

Abbildungsverzeichnis

Abbildung 1: Schichtenmodell zur Programmerarbeitung

Abbildung 2: Änderungskosten mit Verlauf des Projektfortschritts

Abbildung 3: Der Software-Optimierungsprozess

Abbildung 4: Prozess zur „Leistungsoptimierung im Nachhinein“

Abbildung 5: Abläufe in der Planungsphase

Abbildung 6: Abläufe in der Definitionsphase

Abbildung 7: Abläufe in der Vorbereitungsphase

Abbildung 8: Abläufe in der Optimierungsphase

Abbildung 9: Abläufe in der Abschlussphase

Abbildung 10: Struktur des Optimierungskataloges

Abbildung 12: Optimierungsbaustein vom Typ „C++-Klasse“ (Header)

Abbildung 13: Optimierungsbaustein vom Typ „C++-Klasse“ (Teil 1)

Abbildung 14: Optimierungsbaustein vom Typ „C++-Klasse“ (Teil 2)

1 Einleitung

Im Rahmen dieser Diplomarbeit soll untersucht werden, wie der Entwicklungsaufwand für eine nachträgliche Leistungsoptimierung von bereits bestehenden C++-Programmen reduziert werden kann. Mit dem zu entwickelnden Konzept soll sowohl die Effizienz als auch die Wirtschaftlichkeit der Software-Entwicklung im Unternehmen verbessert wer­den.

Dies soll am Beispiel von Programmen der Firma 3D-SHAPE GmbH in Erlangen untersucht werden. Die Firma entwickelt und vermarktet optische Sensoren für berührungslose, 3-dimensionale Formvermessung und Software zur Verarbeitung, Analyse und Bearbeitung der 3-dimensionalen Messdaten.

Um die großen Mengen an Messdaten in akzeptabler Zeit zu verarbeiten, sind hoch optimierte Software-Algorithmen erforderlich.

Die Untersuchungen zur nachträglichen Software-Optimierung sind notwendig, da in vielen Software-Projekten ein Trend zur „Leistungsoptimierung im Nach­hinein“ zu beobachten ist. Die dabei entstehenden Entwicklungskosten sind hier jedoch wesentlich höher als wenn dieser Aspekt bereits in der Anfangsphase der Entwicklung eines Soft­ware-Produktes behandelt worden wäre.

Oft stehen jedoch die vollständige Erfüllung der funktionalen und qualitativen Anforde­rung sowie die termingerechte Auslieferung der Software im Vordergrund. Erst dann, wenn die Rechner-Hardware die Leistungsanforderungen der Software nicht erfüllen kann, werden in der Wartungs- und Pflegephase des Software-Ent­wicklungsprozesses eventuell vorhandene Leistungsdefizite durch Maßnahmen zur Leistungsoptimierung beseitigt. Auf diese Weise erhofft man sich im Allge­meinen das Risiko einer Terminüberschreitung zu reduzieren und unnötigen Optimierungsaufwand einzusparen.

Obwohl das Thema durch den sich abzeichnenden Trend aktuell ist, ist mir keine Literaturstelle bekannt, die ein Konzept anbietet, um den Aufwand einer Leistungsoptimierung in der Wartungs- und Pflegephase eines Software-Pro­jektes zu reduzieren.

Das in dieser Diplomarbeit zu entwickelnde Konzept zur Leistungsoptimierung soll diese Lücke - zumindest teilweise - schließen und dem Software-Entwickler helfen, diese Aufgabe möglichst effizient durchzuführen.

Im Rahmen dieser Arbeit werden daher folgende Tätigkeiten durchgeführt:

- Analysieren jener Prozesse, die im Rahmen eines Entwicklungsprojektes für die nachträgliche Optimierung eines Software-Produktes anfallen.
- Entwerfen eines Konzeptes, um mit Hilfe eines Optimierungskataloges[1] den Aufwand für die „Leistungsoptimierung im Nachhinein“ zu reduzieren.
- Erstellen eines erweiterbaren Optimierungskataloges, der in der Basisver­sion[2] allgemeine Optimierungsbausteine[3] enthält, die dem Entwickler bei der Durchführung einer Optimierungsaufgabe behilflich sind.
- Anhand einer konkreten Aufgabenstellung zeigen, wie das Konzept zur „Leis­tungsoptimierung im Nachhinein“ mit Hilfe des Optimierungskataloges in der Praxis umge­setzt wird.

Aufgrund der umfangreichen Thematik sowie einer konkreten Aufgabenstellung bei der 3D-Shape GmbH in Erlangen, beschränken sich die Untersuchungen rein auf die nachträgliche Leistungsoptimierung von C++-Programmen, die unter einem Windows-Betriebssystem von Microsoft® auf Rechnern mit Prozessoren der Firma Intel® laufen. Das Konzept ist jedoch ohne Probleme auch auf andere Programmiersprachen und Plattformen übertragbar.

2 Theoretische Grundlagen

In diesem Kapitel werden die theoretischen Grundlagen erläutert, auf denen sich die Inhalte der nachfolgenden Kapitel beziehen. Aufgrund der einschränkenden Vorgaben bezüglich des Umfangs der Diplomarbeit wird jedoch nur soweit auf die Theorie eingegangen, wie es für das Verständnis der behandelten Thematik unbedingt notwendig ist. Für eine ausführlichere Darstellung der Theorie wird jeweils auf entsprechende Literatur verwiesen.

Wie in der Einleitung bereits erwähnt, findet eine „Leistungsoptimierung im Nachhinein“ meist in der Wartungs- und Pflegephase eines Software-Projektes statt. Zum besseren Verständnis werden in Kapitel 2.1 die Entwicklungsphasen eines Software-Projektes vorgestellt.

Ein wichtiges Thema bei der Leistungsoptimierung besteht im Testen der Soft­ware, bei dem durch Benchmark-Tests[4] der Projektfortschritt und durch Regressi­ons- und Systemtests die Produktqualität gemessen werden. In Kapi­tel 2.2 werden grundlegende Software-Teststrategien erläutert, die für das Ver­ständnis notwendig sind.

Zur effizienten Leistungsverbesserung eines Software-Programmes muss der Quellcode bezüglich Laufzeitverhalten und Speicherbedarf eingehend analysiert werden. In Kapitel 2.3 werden die wichtigsten Methoden zur Analyse von Algo­rithmen vorgestellt.

Das Konzept zur Leistungsoptimierung setzt auf die Ideen der bausteinbasier­ten Software-Entwicklung[5] auf. In Kapitel 2.4 werden diese Prinzipien kurz erläu­tert.

2.1 Entwicklungsphasen eines Software-Projektes

Alle Aktivitäten, die nötig sind, um ein Software-Produkt zu entwickeln, werden in Phasen unterteilt [Bal01, S.55]. In der Literatur findet man unter­schiedliche Ansätze für Entwicklungsphasen. Bei [Kro97, S.28ff] gibt es sechs Phasen, während [Rich03, S.71ff] einen moderneren Ansatz vorstellt und sich dabei lediglich auf drei Phasen bezieht. Das nachfolgend beschriebene Pha­senmodell von [Bal01, S.51ff] wird jedoch in der Praxis in dieser oder ähnlicher Form häufig eingesetzt.

2.1.1 Die Planungsphase

Bevor mit der eigentlichen Entwicklung eines Software-Produktes begonnen werden kann, muss durch eine Voruntersuchung oder Durchführbarkeitsunter­suchung die fachliche, ökonomische und personelle Durchführbarkeit aufgezeigt werden. Am Ende der Planungsphase steht die Entscheidung über die weitere Vorgehensweise: Weitermachen oder beenden [Bal01, S.58].

Das fachliche Ergebnisdokument der Planungsphase wird oft als Lastenheft oder grobes Pflichtenheft bezeichnet, ergänzt um ein Glossar. Das Lastenheft enthält eine Zusammenfassung aller fachlichen Basisanforderungen, die das zu entwickelnde Software-Produkt aus der Sicht des Auftraggebers erfüllen muss. „Basisanforderungen“ bedeutet eine bewusste Konzentration auf die funda­mentalen Eigenschaften eines Produktes und ihre Beschreibung auf einem aus­reichend hohen Abstraktionsniveau, das die Anforderungen präzise be­schreibt, ohne sich in Details zu verlieren [Bal01, S.63].

Im Glossar sind alle wichtigen Begriffe zu definieren, die zur Beschreibung des Produkts benötigt werden [Bal01, S.65].

Auch bei der „Leistungsoptimierung im Nachhinein“ wird zu Beginn eines Pro­jektes in der Planungsphase ein Lastenheft erstellt, in dem die Anforderungen und Ziele des Projektes beschrieben sind.

2.1.2 Die Definitionsphase

Soll ein neues Software-Produkt erstellt werden, müssen die Anforderun­gen („requirements“) an dieses Produkt in der Definitionsphase von den Anwen­dungsspezialisten und Systemanalytikern in Zusammenarbeit mit dem Auftraggeber und den potentiellen Benutzern oder Benutzerrepräsentanten in Form einer Produktdefinition beschrieben werden [Bal01, S.118].

Eine Produktdefinition besteht meist aus mehreren Dokumenten. Ein Dokument davon ist meist ein verbal beschriebenes Pflichtenheft. Dieses enthält eine Zu­sammenfassung aller fachlichen Anforderungen, die das zu entwickelnde Soft­ware-Produkt aus der Sicht des Auftraggebers erfüllen muss. Insbesondere werden alle nicht formalisierbaren Anforderungen aufgeführt. Außerdem werden Entwicklungsprioritäten aus Auftrag­gebersicht festgelegt [Bal01, S.118f].

Bei der „Leistungsoptimierung im Nachhinein“ wird in der Definitionsphase die Produktumgebung festgelegt. Anschließend werden Anforderungen und Ziele genauer definiert und die Resultate in einem Pflichtenheft festgehalten.

2.1.3 Die Entwurfsphase

Ziel des Entwurfs ist es, ausgehend von der Produktdefinition, einen Produkt­entwurf zu erstellen, der die Software-Architektur beschreibt und die Spezifika­tionen der Systemkomponenten enthält [Bal01, S.716].

Bevor mit dem eigentlichen Entwurf begonnen werden kann, müssen die Einsatzbedingungen des Produkts, die Umgebungs- und Randbedingungen geklärt und festgelegt werden [Bal01, S.716].

Bei der „Leistungsoptimierung im Nachhinein“ entfällt diese Phase, da sich hierbei die Software-Architektur im Allgemeinen nicht verändert. Statt dessen werden in einer Vorbereitungsphase Maßnahmen zur Unterstützung einer Op­timierungsphase durchgeführt.

2.1.4 Die Implementierungsphase

Ziel der Implementierung ist es, die in der Entwurfsphase spezifizierten Sys­temkomponenten durch Programme zu realisieren [Bal01, S.1080f].

Bei der „Leistungsoptimierung im Nachhinein“ wird diese Phase als Optimie­rungsphase bezeichnet. Hier werden neben der Performance-Analyse und dem Benchmarking[6] weitere Aufgaben wie z.B. das Anpassen vorhandener Software-Komponenten durchgeführt.

2.1.5 Die Abnahme- und Einführungsphase

Eine Software-Entwicklung endet mit der Abnahme und Einführung des Pro­dukts. Der Auftraggeber (extern oder intern) testet in der Abnahmephase das fertig gestellte Produkt gegen die in der Produktdefinition festgelegten Anforde­rungen. Nach erfolgter Abnahme wird in der Einführungsphase das Produkt beim externen Auftraggeber (Individual-Software) oder bei Pilotkunden (Stan­dard-Software) installiert und in Betrieb genommen. Die Inbetriebnahme kann durch direkte Umstellung, einen Parallellauf oder einen Versuchslauf erfolgen [Bal01, S.1087]. Mit der erfolgreichen Einführung und der offiziellen Freigabe des Produkts ist die Produktentwicklung beendet [Bal01, S.1089].

Auch bei einem Projekt zur „Leistungsoptimierung im Nachhinein“ gibt es eine ähnliche Entwicklungsphase, die hier jedoch als Abschlussphase bezeichnet wird.

2.1.6 Die Wartungs- und Pflegephase

Mit dem Betriebsbeginn eines Produktes beginnt seine Wartung und Pflege. Bei der Wartung wird ein Produkt durch Fehlerkorrekturen stabilisiert und durch Leistungsverbesserungen optimiert. Bei der Pflege wird ein Produkt durch Än­derungen an die geänderte Umwelt angepasst und durch funktionale Ergän­zungen erweitert. Betrachtet man den Lebenszyklus (life cycle) eines Software-Produktes, dann betragen die Entwicklungskosten zwischen 20% und 33% und die Wartungs- und Pflegekosten zwischen 67% und 80% der gesamten Lebenszykluskosten. Siehe hierzu auch [Bal01, S.1099].

Um den Wartungs- und Pflegeaufwand zu reduzieren schlägt [Bal01, S.1094] eine Verbesserung des Software-Entwicklungsprozesses und eine Verbesse­rung der Produktivität bei der Wartung und Pflege vor.

Diesen Vorschlag nimmt sich diese Diplomarbeit an, indem versucht wird, durch das Erstellen eines Konzeptes den Wartungsaufwand für eine Leistungsverbesserung zu reduzieren.

2.2 Software-Teststrategien

Ganz allgemein lassen sich Tests in Blackbox-Tests und Whitebox-Tests klas­sifizieren. Blackbox-Tests finden aus der Sicht des Anwenders statt. Dabei handelt es sich um Funktionstests[7], da nur interessiert, ob die Funktion ordnungsgemäß erfüllt wird [Alp94, S.40]. Whitebox-Tests fin­den auf der Ebene des Software-Entwicklers statt. Dieses Testverfahren wird auch als strukturiertes Testen bezeichnet, da Testfälle aufgrund bekannter Strukturen ermittelt werden [Alp94, S.40].

Des Weiteren lassen sich Tests auch in dynamische und statische Tests unterteilen. Siehe dazu [Ligg02, S.35ff] und [Alp94, S.39].

2.2.1 Dynamische Tests

Nach [Ligg02, S.36] werden dynamische Tests (Blackbox-Tests) durch folgende Merkmale repräsentiert:

- Die übersetzte, ausführbare Software wird mit konkreten Eingabedaten verse­hen und ausgeführt.
- Es kann in der realen Betriebsumgebung getestet werden.
- Dynamische Tests sind Stichprobenverfahren.

Eine Aussage über die korrekte oder unkorrekte Funktion der Software ist im Grunde ausschließlich für die gewählten Testdaten sicher möglich. Das Ziel der dynamischen Tests ist die Erzeugung von Testfällen, die repräsentativ, fehlersensitiv, redundanzarm und ökonomisch sind [Ligg02, S.36].

Eine spezielle Form der dynamischen Tests sind die Benchmark-Tests. Darun­ter versteht man im Allgemeinen einen Testprozess zur Durchführung einer Leistungsbewertung. Um aussagefähige Testergebnisse zu erhalten, ist es je­doch wichtig, dass solche Tests unter exakt definierten Testbedingungen und mit identischen Testdaten stattfinden.

Im Rahmen der „Leistungsoptimierung im Nachhinein“ werden solche Bench­mark-Tests durchgeführt, um die Leistungsfähigkeit eines zu optimierenden Software-Programmes zu bestimmen und durch Leistungsvergleich den Projekt­fortschritt zu messen.

2.2.1.1 Diversifizierende Tests

Die diversifizierenden Tests sind eine Untergruppe der dynamischen Tests. Sie bewerten die Korrektheit der Testergebnisse durch Vergleich der Ergebnisse mehrerer Software-Testversionen. Vorteil der di­versifizierenden Tests ist die Möglichkeit zur automatisierten Bewertung der Korrektheit der Testergebnisse [Ligg02, S.39].

Eine Form dieser Techniken sind die Regressionstests. Ein Regressionstest besteht aus der Wiederholung von bereits durchgeführten Testläufen. Die zu testende Software ist pro durchzuführenden Testfall in den gleichen Zustand zu versetzen, wie bei der vorhergehenden Durchführung des Testfalls. Es sind
identische Eingabedaten zu verwenden und die neu erzeugten Ausgaben sind mit den Ausgaben der Vorläuferversion zu vergleichen. Falls keine Unter­schiede auftauchen, ist der Regressionstestfall als erfolgreich absolviert anzu­sehen.

Falls Unterschiede erkannt werden, ist zu prüfen, ob diese gewünscht sind oder ob diese fehlerhafterweise aufgetreten sind. Im erstgenannten Fall ist das ge­änderte Verhalten für zukünftige Regressionstests als Soll-Verhalten, also als Referenzfall, zu definieren. Im zweiten Fall muss der Fehler lokalisiert und kor­rigiert werden [Ligg02, S.187].

Bei der „Leistungsoptimierung im Nachhinein“ werden Regressionstests dazu verwendet, um zu kontrollieren, ob die Ergebnisdaten der optimierten Version eines Software-Produktes noch identisch zu den Ergebnisdaten der nicht opti­mierten Version sind.

2.2.1.2 Systemtests

Die Systemtests bilden die abschließenden Tests der Software-Entwickler und Quali­tätssicherer in der realen Umgebung (System-Software, Hardware, Bedie­nungsumfeld, technische Anlage) [Bal98, S.537].

In Abhängigkeit von den gewählten Prüfzielen sind unterschiedliche Systemtests auszuführen. Die wichtigsten werden in der folgenden Tabelle kurz vorgestellt. Siehe hierzu auch [Bal98, S.537].

Abbildung in dieser Leseprobe nicht enthalten

Tabelle 1: Übersicht von Systemtestmethoden

Solche Systemtests kommen auch am Ende eines Projektes zur „Leistungsop­timierung im Nachhinein“ zum Einsatz, um die Software-Qualität zu gewährleis­ten.

2.2.2 Statische Tests

In [Alp94, S.39] versteht man statische Tests als Testmethoden, die sich mit den „system requirements“, dem Design und zum Teil auch mit dem Code be­schäftigen. Nach [Ligg02, S.40] besitzen alle statischen Tests folgende Merk­male:

- Es erfolgt keine Ausführung der zu testenden Software.
- Die Durchführung ist prinzipiell ohne Computerunterstützung möglich.
- Es werden keine Testfälle gewählt.
- Vollständige Aussagen über die Korrektheit oder Zuverlässigkeit können nicht erzeugt werden.

Statische Tests kann man mit Hilfe der folgenden Methoden durchführen:

- Inspektion [Bal98, S.305],
- Review [Bal98, S.317],
- Walkthrough [Alp94, S.43], [Bal98, S.321].

Im Allgemeinen handelt es sich dabei um Prüfmethoden, bei denen in Team-sitzungen Defekte und Probleme in einem schriftlichen Prüfobjekt identifiziert wer­den. Eine ausführliche Darstellung dieser Methoden findet man bei [Bal98, S.324].

Bei der „Leistungsoptimierung im Nachhinein“ wird diese Testmethode dazu verwendet, um einen Quellcode durch eine Code-Inspektion auf uneffiziente und unnötige Algorithmen hin zu untersuchen.

2.3 Analyse von Algorithmen

Eine der Hauptaufgaben bei der „Leistungsoptimierung im Nachhinein“ ist das Analysieren der Leistungsfähigkeit von Algorithmen. In der Praxis sind vor allem Aussagen betreffend des Zeitverhaltens (die Perfor­mance) und dem Speicherplatzbedarf von wesentlicher Bedeutung [BlSchi96, S.96].

In [Sed02, S.50] wird dabei zwischen der empirischen Methode und der mathematischen Methode unterschieden.

2.3.1 Empirische Methode zur Analyse von Algorithmen

[Sed02, S.51] beschreibt die empirische Methode folgendermaßen: „Hat man zwei Algorithmen, die das gleiche Problem lösen, gibt es am Verfahren nichts Geheimnisvolles: Wir führen sie beide aus und stellen fest, welcher Algorithmus länger braucht“.

Folgende Probleme sind dabei nach [Sed02, S.51f] zu lösen:

- Für die Analyse muss eine korrekte und vollständige Implementierung entwi­ckelt werden. Für manche komplexe Algorithmen kann das ein echtes Hin­dernis darstellen.
- Das Wesen der Eingabedaten und andere Faktoren müssen bestimmt wer­den, die sich direkt auf die durchgeführten Experimente auswirken. Prinzi­piell hat man die drei Möglichkeiten: tatsächliche Daten, zufällige Daten oder extreme Daten verwenden. Mit tatsächlichen Daten kann man die re­alen Kosten des verwendeten Programms messen. Zufällige Daten geben einem die Gewissheit, dass das Experiment den Algorithmus und nicht die Daten testet. Schließlich gewährleisten extreme Daten, dass das Pro­gramm mit jeder Art von Eingaben umgehen kann.
- Wenn man Implementierungen vergleicht, schleichen sich leicht Fehler ein. Vor allem wenn sich die Tests auf unterschiedliche Computer, Compiler
oder Systeme erstrecken oder wenn man größere Programme mit schlecht spe­zifizierten Eingaben vergleicht.

In der Praxis ist die Analyse nach der empirischen Methode weit verbreitet. Für diesen Zweck sind in modernen Entwicklungsumgebungen oftmals bereits Profiler-Tools[8] integriert. Das Ergebnis dieser Methode ist eine Aussage über die Laufzeit eines Software-Produktes unter bestimmten Bedingungen.

Auch bei einem Projekt zur „Leistungsoptimierung im Nachhinein“ wird in der Regel diese Methode verwendet.

2.3.2 Mathematische Methode zur Analyse von Algorithmen

Sobald empirische Untersuchungen unverhältnismäßig viel Zeit erfordern, ist die mathematische Methode gefragt. Für diesen Zweck gibt es die Standard-notation, die sogenannte O-Notation[9] [KePi00, S.46]. Diese wurde bereits 1894 von dem Mathematiker Paul Gustav Heinrich Bachmann (1837-1920) eingeführt und von [Knu76, S.18] für die Analyse von Algorithmen „wieder entdeckt“. Der grundlegende Parameter der O-Notation ist n, die Größe einer bestimmten Ausprägung eines Problems. Die Komplexität oder Laufzeit von einem Algorithmus wird als Funktion von n ausgedrückt.

Das „O“ steht für das englische „o rder“ und gibt eine Größenordnung für das Laufzeitverhalten an. Die Notation O(f(n)) bedeutet, dass die Laufzeit proportional zu höchstens f(n) ist, wenn n hinreichend groß ist [KePi00, S.46]. In der folgenden Tabelle sind die wichtigsten Fälle für Komplexitäten aufgelistet, die Algorithmen haben können. Siehe hierzu [KePi00, S.47] und [Ern00, S.429]:

Abbildung in dieser Leseprobe nicht enthalten

Tabelle 2: Mögliche Komplexitäten von Algorithmen[10] [11]

Bei der „Leistungsoptimierung im Nachhinein“ wird diese Methode wohl nur in Ausnahmefällen angewendet. Für die Beurteilung der Leistungsfähigkeit eines Software-Produktes sind eben Aussagen wie „Das Programm ‚P’ benötigt für die Bearbeitung der Daten ‚D’ genau ‚n’ Sekunden“ für die Marketingabteilung oder den Kunden wohl eher verständlich, als eine Aussage der mathematischen Methode wie zum Beispiel: „Das Programm ‚P’ hat die Komplexität O( log n )“.

2.4 Bausteinbasierte Software-Entwicklung

Objektorientierte Programme können auf verschiedenartige Weise erarbeitet werden. In [Bau00, S.1] wird dafür folgendes Schichtenmodell angegeben:

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 1: Schichtenmodell zur Programmerarbeitung

Programmerarbeitung auf dem Niveau der Bausteine unterstützt die Forderung nach Wiederverwendbarkeit. Die Überlegung, auf vorgefertigte Komponenten zurückzugreifen, ist bereits mit der Entwicklung symbolischer Programmiersprachen entstanden und wird seitdem in Form von Makros oder Programm-bibliotheken verwirklicht [Bau00, S.1].

Im Rahmen der Objektorientierung wird nun der Gedanke der Wiederverwen­dung erneut aufgegriffen und forciert. Aus diesem Grunde wird die Betrachtung zu objektorientierten Programmen auf dieser Ebene durchgeführt [Bau00, S.1].

Für den Begriff Baustein wird in [Bau00, S.2] folgende Erläuterung gegeben:

Ein Baustein ist ein bestimmter Typ von Software-Komponenten. Typbildendes Merkmal ist der Aufbau nach dem Open-Closed-Prinzip.

Open Eine Software-Komponente ist offen, wenn sie erweitert werden kann, ohne dass der vorhandene Quellcode verändert werden muss oder existierende Clients davon berührt werden.

Closed Eine Software-Komponente ist abgeschlossen, wenn sie mit einer definierten Schnittstelle für die Wiederverwendung zur Verfügung gestellt werden kann.

Im Rahmen des Konzeptes zur „Leistungsoptimierung im Nachhinein“ wird der Begriff Baustein ausgedehnt. Unter die­sen Begriff fallen hier sowohl reine C++-Bausteine[12] als auch Textbausteine (Formu­lare und Dokumente) sowie komplette Programmbausteine (Hilfsprogramme), die alle ein Ziel verfolgen, nämlich die Wiederverwendung im Rahmen einer Software-Leistungsoptimierung. Alle diese genannten Bausteine erfüllen die Bedingun­gen für das oben beschriebene Open-Closed-Prinzip.

Eine ausführliche Erläuterung zum Thema Software-Bausteine findet sich in [Bau00]. Weiterführende Informationen finden sich auch bei [GrTh00]. Das Thema „Software-Wiederverwendung“ wird bei [Küf94] ausführlich behandelt.

3 „Leistungsoptimierung im Nachhinein“

Das Optimieren der Ausführungsgeschwindigkeit eines Software-Produktes am Ende eines Entwicklungsprojektes oder gar erst nach Freigabe und Ausliefe­rung in der Wartungs- und Pflegephase ist bekanntermaßen sehr zeitaufwendig und teuer. Im Allgemeinen wird davon ausgegangen, dass die Kosten für Ände­rungen mit dem Projektfortschritt exponentiell steigen [vgl. Beck00, S.21].

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 2: Änderungskosten mit Verlauf des Projektfortschritts

Trotzdem kann man in konkreten Software-Projekten immer wieder beobach­ten, dass solche Optimierungsaufgaben an das Ende eines Software-Entwick­lungsprojektes gestellt werden. In einem Artikel der Zeitschrift IEEE Software [Smith91, S.95] wurde bereits vor über zehn Jahren auf diese Problema­tik aufmerk­sam gemacht: „Fixing it later was a viable approach in the 1970s, but today it is dangerous. Performance-Engineering methods fall between the extremes of ‘performance-driven development’ and ‘fixing it later’”.

Dass diese Problematik mehr als zehn Jahre später immer noch aktuell ist, belegt die folgende Aussage aus dem Fachartikel [EvSchDu02, S.74]:

„Examining performance at the end of software development is a common industrial practice, but it can lead to using more expensive and powerful hardware than originally proposed, time-consuming tuning measures, or (in extreme cases) completely redesigning the application…. To avoid such costs, a system’s performance characteristics must be considered throughout the whole software development process”.

3.1 Notwendigkeit einer Leistungsoptimierung

Trotz ständig steigender Rechenleistung der Hardware ist eine Leistungsopti­mierung von Software-Produkten oftmals unumgänglich. Wie die folgenden Bei­spiele zeigen, machen es die aktuellen Anforderungen an die Rechengeschwin­digkeit und die zu verarbeitende Datenmengen nach wie vor erforderlich, dass die Ressource „Hardware“ von der Software möglichst effizient ge­nutzt wird.

Multimedia-Applikationen

Bilddaten sollen möglichst 3-dimensional sein und eine möglichst große und realistische Auflösung mit immer mehr Farben besitzen. Bewegte Bilder sind schon fast selbstverständlich. Solche Anforderungen sind selbst mit den neues­ten Rechnergenerationen nur dann zu erfüllen, wenn effiziente Algorithmen ein­gesetzt werden.

Datenbanken

In Datenbanken steigt die Menge der zu verwaltenden Daten drastisch an. Im­mer mehr Informationen werden gesammelt. Dies erfordert auch immer kom­plexere Auswertungen, deren Ergebnisse dennoch möglichst sofort verfügbar sein sollen.

Hardware-Geschwindigkeit

Die Hardware wird immer schneller und liefert immer größere Mengen an Daten. So steigt nicht nur die Datenmenge selbst, sondern auch die Zeit wird immer kürzer, in der die Daten verarbeitet werden müssen.

Betriebssystem

In einer Multitasking-Umgebung belegen gleichzeitig mehrere Programme einen Teil der verfügbaren Gesamtrechenleistung eines Rechners. Auch die Anforde­rungen an diese Programme werden immer komplexer. Dennoch erwartet der Anwender, dass er von der Ressourcen-Aufteilung möglichst nichts bemerkt und alle Programme scheinbar „gleichzeitig“ ablaufen.

Weitere Beispiele finden sich bei [Joh98, S.280] in dem Artikel „High-Speed, Wide Area, Data Intensive Computing: A Ten Year Retrospective”.

3.2 Gründe für eine „Leistungsoptimierung im Nachhinein“

Der Trend, eine Leistungsoptimierung erst am Ende oder nach der Freigabe eines Software-Projektes durchzuführen, hat sich aus verschiedenen Motiven heraus entwickelt. Zwei davon werden im Folgenden vorgestellt.

3.2.1 Abschätzungsrisiken vermeiden

Die Projektleitung hat die Aufgabe, die Software termingerecht zu den geplan­ten Kosten und in der geplanten Qualität auszuliefern [Brö00, S.291]. Der notwen­dige Zeitaufwand für die Entwicklung einer leistungsoptimierten Software ist jedoch sehr schwer abzuschätzen.

Durch die Strategie der „Leistungsoptimierung im Nachhinein“ hofft man nun, das Risiko einer Terminüberschreitung zu reduzieren. Erst nachdem die Entwicklung der Funktionalität eines Software-Produktes ab­geschlossen ist, wird die restli­che zur Verfügung stehende Projektzeit genutzt, um Optimierungsmaß­nahmen durchzuführen. Fehlt diese Zeit, dann wird die Optimierung häufig erst nach Freigabe der Software in der Wartungs- und Pflegephase des Software-Pro­duktes durchgeführt. Siehe auch [Bal01, S.1091].

3.2.2 Rechengeschwindigkeit der Hardware nutzen

Gordon Moore (ehem. Gründer und CEO von Intel®) hat 1965 die Prognose aufgestellt, dass sich die Transistordichte integrierter Schaltkreise alle 18 Mo­nate verdoppelt [Moo65]. Entsprechend erhöht sich auch die Leistungsfähigkeit von Mikroprozessoren. Diese durch die Medien als „Mooresches Gesetz“ be­kannt gewordene Prognose hat bis heute seine Gültigkeit bewahrheitet und wird dies nach Einschätzung von Moore selbst [Moo03] auch für die nächsten zehn Jahre noch tun.

Bei der Strategie der „Leistungsoptimierung im Nachhinein“ beginnt man mit den Leistungstests erst am Ende der Software-Entwicklung, um dann (unter Einsatz aktueller Hardware) eventuell noch vorhandene Leistungsdefizite aufzuspüren und durch Software-Optimierung zu beseitigen.

3.3 Verbesserung der „Leistungsoptimierung im Nachhinein“

Die Informatik-Theorie empfiehlt, eine Leistungsoptimierung möglichst frühzeitig im Software-Entwicklungsprozess zu berücksichtigen. Wie man in den Kapiteln 3.2.1 und 3.2.2 sehen kann, sind in der Praxis immer noch Motive vorhanden, diese Ratschläge und Empfehlungen zu ignorieren und erst in der letzten Phase einer Soft­ware-Entwicklung mit der Leistungsoptimierung zu beginnen.

Die Verbesserung der „Leistungsoptimierung im Nachhinein“ hat als Hauptziel, den da­bei anfallenden Entwicklungsaufwand möglichst gering zu halten. Um dieses Ziel zu erreichen, sind zuvor mehrere Arbeitsschritte durchzuführen.

- Zunächst einmal ist es notwendig, die Entwicklungsphasen einer „Leistungsop­timierung im Nachhinein“ zu kennen. Diese Entwicklungsphasen werden daher in Kapitel 4 (Prozess zur „Leistungsoptimierung im Nachhinein“) analysiert und aufgezeigt.
- Auf Grundlage der analysierten Entwicklungsphasen ist ein ganzheitliches Konzept zu entwerfen, welches das Ziel hat, den notwendigen Zeitbedarf und damit die Entwicklungskosten für die Optimierung eines Software-Produktes zu reduzie­ren. In Kapitel 5 wird dazu ein Konzept zur „Leistungsoptimierung im Nachhinein“ vorgestellt.
- Durch die Umsetzung des Konzeptes zur „Leistungsoptimierung im Nachhinein“ sollen Rahmenbedingungen geschaffen werden, die dem Entwickler helfen, die erforderlichen Aufgaben effizienter zu realisieren. Diese Umsetzung wird in Kapitel 6 durch die Entwicklung eines Optimierungskataloges beschrieben.
- Durch die Anwendung des Konzepts zur „Leistungsoptimierung im Nachhinein“ ist festzustellen, ob das ange­strebte Ziel, nämlich die Reduzierung des Entwicklungsaufwandes, erfüllt werden kann. In Kapitel 7 werden die Erfahrungen mit einer solchen Anwendung beschrieben.

4 Prozess zur „Leistungsoptimierung im Nachhinein“

Software-Produkte werden selten vor der ersten Freigabe optimiert. Sobald ein Produkt funktionsfähig ist, wird es freigegeben. Die Optimierung bleibt der Wartung vorbehalten [Bal01, S.1091].

In [Ger02, S.7] wird der Prozess zur „Leistungsoptimierung im Nachhinein“ folgendermaßen dar­gestellt:

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 3: Der Software-Optimierungsprozess

Die im Folgenden beschriebenen Entwicklungsphasen lehnen sich an die aus der Theorie bekannten Entwicklungsphasen eines Software-Projektes an [Bal01, S.51ff]. Diese wurden jedoch an die besonderen Anforderungen und Aufgaben einer „Leistungsoptimierung im Nachhinein“ angepasst.

Der Prozess zur „Leistungsoptimierung im Nachhinein“ lässt sich in folgende Entwicklungsphasen unterteilen:

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 4: Prozess zur „Leistungsoptimierung im Nachhinein“

4.1 Planungsphase

Bevor mit der eigentlichen Optimierung begonnen werden kann, muss durch eine Funktionsanalyse ermittelt werden, welche Teilfunktionen eines Software-Produktes optimiert werden müssen. Für jede dieser Teilfunktionen ist ein Leistungsziel festzulegen. Die Analyseergebnisse und Projektziele sind in einem Lastenheft zu beschreiben. Anschließend kann eine Aufwandsabschätzung erfolgen.

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 5: Abläufe in der Planungsphase

4.1.1 Funktionsanalyse durchführen

Durch die Funktionsanalyse soll ermittelt werden, welche Teilfunktionen eines Software-Produktes in Bezug auf die Geschwindigkeit als zu langsam eingestuft und optimiert werden sollen. Ein Software-Produkt komplett zu optimieren wäre viel zu teuer und auch wenig sinnvoll, da es immer Programmteile gibt, die keinen Einfluss auf das Gesamtlaufzeitverhalten des Programms haben, weil diese beispielsweise recht selten oder nur in Sonderfällen aufgerufen werden.

Im Folgenden werden mögliche Gründe genannt, die dazu führen, dass ein Software-Produkt oder eine Software-Funktion als zu langsam eingestuft wird:

- Der Benutzer wird in seinem „Eingabefluss“ gebremst (Sanduhr).
- Der Benutzer empfindet die Ausführungsgeschwindigkeit einer Funktion des Programms als zu langsam.
- Ein direkter Leistungsvergleich zwischen gleichen Funktionen unterschiedlicher Programme auf gleicher Hardware ergibt Laufzeitunterschiede.
- Eine Funktion ist zu langsam, wenn dadurch andere Funktionen, die in Wechselwirkung zu dieser agieren, in ihrer Ausführung gebremst werden. Beispiel: Eine Funktion schreibt Datenblöcke in einen Puffer, eine andere Funktion liest und entfernt diese Daten wieder. Ist die Lesefunktion langsa­mer als die Schreibfunktion, läuft der Datenpuffer voll. Die Schreibfunktion muss also warten bis im Datenpuffer wieder Platz ist.
- Eine Funktion ist zu langsam, wenn eine Hardware-Komponente die Daten (z.B. Bilddaten einer Kamera) schneller liefert, als die Funktion sie abarbeiten kann.

Eine Funktionsanalyse wird zumeist im Rahmen einer Besprechung durchge­führt. Neben den Entwicklern und Projektleitern können die Teilnehmer auch aus Kunden oder Vertriebsleuten bestehen.

4.1.2 Leistungsziel festlegen

Die Geschwindigkeitsoptimierung einer Software ist eine Aufgabe, die kein kla­res Abschlusskriterium hat. Selbst eine bereits optimierte Software kann mit entsprechend hohem Aufwand meist noch weiter optimiert werden. Damit ein Optimierungsprojekt dennoch nicht zu einem Endlosprojekt wird, ist es wichtig, bereits bei Projektbeginn ein Maß für das zu erreichende Ziel zu finden. Dies kann beispielsweise durch Festlegung von Kennzahlen erfolgen, die angeben, um welchen Leistungsfaktor eine Teilfunktion optimiert werden soll. Dabei ist es empfehlenswert, für jede Teilfunktion jeweils ein Minimum und ein Maximum anzugeben.

4.1.3 Lastenheft erstellen

Das Lastenheft ist das Ergebnisdokument der Planungsphase. In der Defini-tionsphase wird das Lastenheft dann zum Pflichtenheft erweitert und verfeinert [Bal01, S.62].

Für die Aufgabe der „Leistungsoptimierung im Nachhinein“ empfiehlt sich für den Inhalt des Lastenheftes folgendes Gliederungsschema:

Abbildung in dieser Leseprobe nicht enthalten

Tabelle 4: Gliederungsschema für das Lastenheft

4.1.4 Entwicklungsaufwand abschätzen

Die Aufwandsabschätzung dient zur groben Festlegung des Entwicklungsauf­wands für die im Lastenheft festgelegten Anforderungen. Eine ausführliche Übersicht über vorhandene Schätzmethoden findet sich bei [Bal01, S.73ff], [Kro97, S.219ff] und [Brö00 S.292ff].

Eine Aufwandsabschätzung an dieser Stelle des Projektes durchzuführen ist eine schwierige Aufgabe. Bei einer Abschätzung müssen viele Faktoren be­rücksichtigt werden. Wie stark diese Faktoren die Abschätzung beeinflussen ist von Erfahrungswerten abhängig. Aufgrund der hohen Komplexität, die sich bei der Aufgabe „Leistungsoptimierung im Nachhinein“ ergibt, sind die Schätzwerte meist relativ ungenau. Für eine Verbesserung der Abschätzung sollten die Schätzwerte im Laufe des Projektes aktualisiert werden.

Im Folgenden wird eine Auswahl an Einflussfaktoren vorgestellt, die man bei einer Aufwandsabschätzung berücksichtigen kann:

Abbildung in dieser Leseprobe nicht enthalten

Tabelle 5: Einflussfaktoren bei der Aufwandsabschätzung[13]

4.2 Definitionsphase

In der Definitionsphase werden die Anforderungen für das optimierte Software-Produkt näher definiert. Das Ergebnis der Definitionsphase ist ein Pflichtenheft (verfeinertes Lastenheft). Das Pflichtenheft ist die Basis für die Abnahme des fertigen Produktes [Bal01, S.113].

Durch Festlegen der Produktumgebung wird bestimmt, auf welcher Hardware-Plattform das optimierte Software-Produkt einsetzbar sein muss. Ebenso wer­den die Leistungsanforderungen an das Software-Produkt festgelegt. Die Ergebnisse werden in einem Pflichtenheft festgehalten.

Abbildung in dieser Leseprobe nicht enthalten

Abbildung 6: Abläufe in der Definitionsphase

4.2.1 Produktumgebung festlegen

Mit Festlegung der Produktumgebung wird angegeben, auf welcher Rechner­plattform das Software-Produkt lauffähig sein muss. Diese Angaben sind notwendig, da die Möglichkeiten zur Software-Optimierung abhängig von der verwendeten Hardware-Plattform und dem eingesetzten Betriebssystem sein kann. Folgende Angaben sind für die Definition der Produktumgebung von Bedeutung:

Abbildung in dieser Leseprobe nicht enthalten

Tabelle 6: Angaben zur Produktumgebung

4.2.2 Anforderungen spezifizieren

Die Basisanforderungen leiten sich aus den Angaben des Lastenheftes ab. Dieses enthält Angaben zu den zu optimierenden Teilfunktionen sowie zu den zu erreichenden Leistungszielen. Diese Anforderungen werden hier ergänzt bzw. verfeinert.

Falls sich durch die Leistungsoptimierung der Software Änderungen an den Schnittstellen ergeben, dann sind diese Änderungen ebenfalls hier zu beschreiben.

[...]


[1] Sammlung von Optimierungsbausteinen zur Unterstützung des Software-Entwicklers bei Software-Optimierungsprojekten.

[2] Version eines Software-Produktes, welches eine minimale Grundfunktionalität bietet und durch zusätzliche Funktionalitäten erweitert werden kann.

[3] Komponenten in unterschiedlichen Formen (wie C++-Klasse, Formular, etc.) zur Unterstützung eines Optimierungsprozesses.

[4] Testprozess zur Durchführung einer Leistungsbewertung.

[5] Darunter versteht man im Allgemeinen die Zusammensetzung von Software-Programmen aus Standardkomponenten unterschiedlicher Hersteller.

[6] Vorgang einer Leistungsbewertung

[7] Ein Test, der die korrekte und vollständige Funktionalität eines Software-Produktes nachweist.

[8] Software-Tool zum Ermitteln der Ausführungsgeschwindigkeit und Ausführungshäufigkeit von Codeanweisungen in einem Software-Programm.

[9] Die O-Notation trifft Aussagen über die Komplexität bzw. Ordnung von Algorithmen.

[10] Das „Sieb des Eratosthenes“ ist ein Algorithmus zur Ermittlung von Primzahlen.

[11] Bei dem Problem des Handlungsreisenden sind n Städte und deren Entfernung zueinander gegeben. Es ist der kürzeste Weg zu bestimmen, bei dem jede Stadt genau einmal besucht wird.

[12] Komponenten, die als Untermenge der Optimierungsbausteine aus C++-Klassen bestehen.

[13] Software-Tool zum Ermitteln von Leistungsschwächen in Software-Programmen.

Details

Seiten
67
Erscheinungsform
Originalausgabe
Jahr
2003
ISBN (eBook)
9783836614610
Dateigröße
648 KB
Sprache
Deutsch
Katalognummer
v225877
Institution / Hochschule
Private FernFachhochschule Darmstadt; Standort Pfungstadt – Informatik
Note
1,5
Schlagworte
leistungsoptimierung performance programm entwicklungsprozess

Autor

Teilen

Zurück

Titel: Konzept zur Leistungsoptimierung von C++-Programmen