<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
  <!ENTITY kcachegrind '<application
>KCachegrind</application
>'>
  <!ENTITY cachegrind "<application
>Cachegrind</application
>">
  <!ENTITY calltree "<application
>Calltree</application
>">
  <!ENTITY callgrind "<application
>Callgrind</application
>">
  <!ENTITY valgrind "<application
>Valgrind</application
>">
  <!ENTITY oprofile "<application
>OProfile</application
>">
  <!ENTITY kappname "&kcachegrind;">
  <!ENTITY package "kdesdk">
  <!ENTITY % addindex "IGNORE">
  <!ENTITY % German "INCLUDE">
]>

<!-- ................................................................ -->

<book lang="&language;">

<bookinfo>
<title
>Das Handbuch zu &kcachegrind;</title>

<authorgroup>
<author
><firstname
>Josef</firstname
> <surname
>Weidendorfer</surname
> <affiliation
> <address
><email
>Josef.Weidendorfer@gmx.de</email
></address>
</affiliation>
</author>

<othercredit role="translator"
><firstname
>Thomas</firstname
><surname
>Reitelbach</surname
><affiliation
><address
><email
>tr@erdfunkstelle.de</email
></address
></affiliation
><contrib
>Deutsche Übersetzung</contrib
></othercredit
> 

</authorgroup>

<copyright>
<year
>2002-2004</year>
<holder
>&Josef.Weidendorfer;</holder
>	
</copyright>
<legalnotice
>&FDLNotice;</legalnotice>

<date
>2004-07-27</date>
<releaseinfo
>0.4.6</releaseinfo>

<abstract>
<para
>&kcachegrind; ist ein KDE-Werkzeug zur Visualisierung von Profiler-Daten. </para>
</abstract>

<keywordset>
<keyword
>KDE</keyword>
<keyword
>kdesdk</keyword>
<keyword
>Cachegrind</keyword>
<keyword
>Callgrind</keyword>
<keyword
>Valgrind</keyword>
<keyword
>Profiling</keyword>
</keywordset>

</bookinfo>


<chapter id="introduction">
<title
>Einleitung</title>

<para
>&kappname; ermöglicht das Durchsehen der Profildaten, die von einem Profiler erzeugt wurden. In diesem Kapitel wird erklärt, warum man Profiler-Daten erhebt und wie man sie erzeugt. Außerdem werden einige verfügbare Profiler-Werkzeuge vorgestellt. </para>

<sect1 id="introduction-profiling">
<title
>Profiling</title>

<para
>Wenn ein Programm entwickelt wird, gehört es zu den abschließenden Schritten, es in der Geschwindigkeit zu optimieren. Es ist natürlich nicht sinnvoll, die Funktionen zu optimieren, die selten aufgerufen werden. Daher muss der Programmautor wissen, in welchem der Programmabschnitt die meiste Zeit verbraucht wird. </para>

<para
>Für sequentiell ablaufenden Code reicht es in der Regel aus, statistische Daten über die Laufzeiteigenschaften des Programms zu ermitteln. Dazu gehört die in bestimmten Funktionen verbrachte Zeit und die zugehörigen Codezeilen. Das Erheben dieser Daten nennt man Profiling. Dabei läuft das Programm in einer kontrollierten Laufzeitumgebung des Profiling-Werkzeugs ab, welches am Ende des Durchlaufs eine Zusammenfassung der gesammelten Daten ausgibt. Im Gegensatz dazu gibt es auch parallel ablaufenden Code. Geschwindigkeitsprobleme resultieren hier häufig daraus, dass ein Prozessor auf Daten eines anderen Prozessors warten muss. Diese Wartezeit lässt sich nicht ohne Weiteres ermitteln und zuordnen; in einem solchen Fall müssen Ereignisse mit Hilfe von Zeitstempeln rückverfolgt werden. Diese Art Daten kann &kcachegrind; nicht anzeigen. </para>

<para
>Nach der Analyse der erzeugten Profiling-Daten sollte es ein Leichtes sein, den möglichen Flaschenhals im Code aufzufinden: Beispielsweise kann man den Code in besonders häufig aufgerufenen Funktionen optimieren. Danach sollte man den Erfolg der Optimierungen mit einem erneuten Profiler-Durchlauf überprüfen. </para>
</sect1>

<sect1 id="introduction-methods">
<title
>Profiling-Methoden</title>

<para
>Um verbrauchte Zeit zu messen oder eingetretene Ereignisse in einem bestimmten Code-Bereich aufzuzeichnen (&eg; einer Funktion) muss zusätzlicher Code vor und hinter dem fraglichen Bereich einprogrammiert werden. Dieser Code misst dann die Zeit oder liest einen globalen Ereigniszähler aus und berechnet die Unterschiede. Diese Veränderung des Original-Codes nennt man Instrumentieren. Die Instrumentierung kann der Programmierer, der Compiler oder auch die Laufzeitumgebung einrichten. Die fraglichen Code-Bereiche sind zumeist verschachtelt und der Aufwand für die Messung dieser Bereiche beeinflusst immer auch die Messergebnisse. Daher sollte die Methode der Instrumentierung nur in ausgewählten Bereichen angewandt und die Ergebnisse mit Bedacht ausgewertet werden. Dieser Umstand macht eine wirklich exakte Messung zu einer äußerst komplexen Aufgabe.</para>

<para
>Eine exakte Messung ist dennoch möglich, nämlich mit Hilfe von Hardware-Zählwerken, so wie sie in den heutigen modernen Prozessoren vorkommen. Diese Zähler inkrementieren mit jedem auftretenden Ereignis. Wir möchten auftretende Ereignisse bestimmten Code-Bereichen zuordnen können. Ohne Hardware-Zähler müssten wir jedes Ereignis selbst mit Hilfe von Software zählen - was natürlich nicht möglich ist. Unter der Annahme, dass die Ereignisverteilung im Quell-Code gleichmäßig ist, wurde jedoch eine Methode entwickelt, die nur jedes n-te Ereignis untersucht - wodurch die <quote
>Kosten</quote
> der Messung beeinflussbar sind: Sampling. Zeitbasiertes Sampling (Time Based Sampling, TBS) untersucht in regelmäßigen Zeitabständen den Programmzähler und erzeugt ein Histogramm über den Programmcode. Das ereignisbasierte Sampling (Event Based Sampling, EBS) untersucht im Gegensatz dazu den Hardware-Zähler moderner Prozessoren. Dazu wird eine Interrupt-Leitung verwendet, die bei einem Zähler-Niedrigstand auslöst; daraufhin wird ein Histogramm der zugehörigen Ereignisverteilung erzeugt: Innerhalb dieser Routine wird der Ereigniszähler wieder auf das Element ‚n‘ der Sampling-Methode zurückgesetzt. Der Vorteil des Sampling ist, dass der Programmcode nicht verändert werden muss. Aber es handelt sich immer noch um eine Kompromisslösung: Die Methode misst genauer, wenn ‚n‘ möglichst klein ist. Mit schrumpfendem ‚n‘ steigen jedoch auch die Kosten für die Messung über die Interrupt-Leitung.</para>

<para
>Eine weitere Messmethode ist es, bestimmte Ereignisse im Rechner zu simulieren, während der fragliche Code läuft; eine geführte Simulation. Eine solche Simulation wird von einem mehr oder weniger genauen Rechnermodell abgeleitet. Mit exakten Rechnermodellen sind ziemlich genaue Rückschlüsse auf die Realität möglich - jedoch ist der für solche Tests nötige Zeitaufwand in der Praxis oft inakzeptabel. Der Vorteil einer Simulation ist, dass im Grunde beliebig komplexer Messungs-Code in den Quell-Code eingefügt werden kann, ohne die Messergebnisse zu beeinflussen. Dies direkt vor der Ausführung (Laufzeit-Instrumentierung) mit der Original-Binärdatei durchgeführt ist für den Benutzer sehr komfortabel: Es ist kein erneutes Kompilieren erforderlich. Eine Simulation ist dann sinnvoll, wenn nur Teile einer Maschine mit einem einfachen Modell simuliert werden sollen. Ein weiterer Vorteil ist, dass die Messergebnisse aus Simulationen einfacher Rechnermodelle auch leichter zu interpretieren sind: oftmals ist das Problem mit echter Hardware, dass sich Ereignisse verschiedener Rechnermodule überschneiden.</para>
</sect1>

<sect1 id="introduction-tools">
<title
>Profiling-Werkzeuge</title>

<para
>Am bekanntesten ist der GCC-Profiler <application
>gprof</application
>: Man muss das Programm mit der Option <option
>-pg</option
> kompilieren. Bei der Programmausführung wird dann eine Datei namens <filename
>gmon.out</filename
> erzeugt, die mittels <command
>gprof</command
> in ein leserliches Format umgewandelt werden kann. Ein Nachteil ist natürlich das notwendige Rekompilieren des Programms, welches außerdem statisch gelinkt werden muss. In diesem Fall wird compilergenerierte Instrumentierung angewandt - alle Aufrufe rund um Funktionen und die zugehörigen Funktionsaufrufe werden gemessen. Zusammen mit zeitbasiertem Sampling (TBS) ergibt sich daraus ein Histogramm der Verteilung der verbrauchten Zeit im Code. Aus den beiden Zeiten lässt sich die Zeit errechnen, die ein Programm in bestimmten Funktionen und den von dort aufgerufenen Funktionen verbringt. </para>

<para
>Es gibt auch Bibliotheken zur exakten Messung aufgetretener Ereignisse. Diese sind in der Lage, Hardware-Zeitgeber auszulesen. Am bekanntesten sind der Patch PerfCtr für &Linux; und die architekturunabhängigen Bibliotheken PAPI und PCL. Dennoch ist zur exakten Messung eine Instrumentierung des Codes nötig. Man kann dazu entweder die Bibliotheken selbst oder automatische Systeme wie ADAPTOR (für FORTRAN-Quellcode) oder DynaProf (Code-Einschleusung über DynInst) verwenden.</para>

<para
>&oprofile; ist ein systemweites Profiling-Werkzeug für &Linux;. Es verwendet Sampling.</para>

<para
>Eine sehr komfortable Möglichkeit des Profiling ist es jedoch, &cachegrind; oder &callgrind; zu verwenden. Dabei handelt es sich um Simulatoren, die auf das Instrumentierungs-Grundgerüst von &valgrind; aufsetzen. Diese sind eine gute Alternative zu den anderen Profiling-Werkzeugen, weil keine Hardware-Zähler verwendet werden (oftmals ist das mit heutigen &Linux;-Installationen schwierig) und die Programmdateien nicht verändert werden müssen. Der Nachteil einer Simulation ist natürlich die Geschwindigkeitseinbuße. Diese kann allerdings reduziert werden, indem man die Simulation auf die interessanten Programmabschnitte beschränkt. Ohne Messung bzw. Simulation der Instrumentierung reduziert &valgrind; die Geschwindigkeit um den Faktor 3 bis 5. Wenn nur das Aufruf-Diagramm und die Anzahl der Funktionsaufrufe von Interesse sind, kann man den Cache-Simulator ganz ausschalten. </para>

<para
>Die Cache-Simulation ist der erste Schritt zur Abschätzung der echten Zeiten. Auf zeitgemäßen Rechnern ist die Laufzeit von Programmen stark abhängig von der Ausnutzung des sogenannten Aufruf-Caches (kleine und sehr schnelle Puffer, die erneuten Zugriff auf die gleichen Speicherbereiche erheblich beschleunigen). &cachegrind; führt eine Cache-Simulation durch, in der die Speicheradressen abgefangen werden. Die erhobenen Daten enthalten auch die Anzahl der Instruktionen, Zugriffe auf Daten-Bereiche im Cache sowie fehlgeschlagene Zugriffe auf 1st-/ und 2nd-Level-Cache. Diese Informationen werden den entsprechenden Code-Zeilen und Funktionen des Programms zugeordnet. Durch eine geschickte Kombination der erhaltenen Daten lässt sich eine gute Abschätzung der benötigten Zeit ermitteln. </para>

<para
>&callgrind; ist eine Erweiterung für &cachegrind;, die das Aufruf-Diagramm eines Programms zur Laufzeit erzeugt. Ein Aufruf-Diagramm gibt Auskunft darüber, welche Funktionen die anderen Funktionen aufrufen und wieviele Ereignisse in einem Funktionsdurchlauf abgearbeitet werden. Des Weiteren können die zu sammelnden Profiler-Daten nach Threads und Aufrufketten-Kontext unterteilt werden. Mit Callgrind ist es möglich, Profiling-Daten auf Instruktions-Ebene zu erhalten und damit auch disassemblierten Code zu untersuchen. </para>
</sect1>

<sect1 id="introduction-visualization">
<title
>Darstellung</title>

<para
>Profiling-Werkzeuge erzeugen für gewöhnlich eine sehr große Datenmenge. Durch diese sollte man möglichst einfach im Aufruf-Diagramm auf und ab navigieren können. Außerdem sollte man schnell und komfortabel zwischen verschiedenen Sortier-Modi für Funktionen und verschiedenen Ansichten für Ereignistypen umschalten können. Es bietet sich daher an, diese Aufgabe einem Programm mit grafischer Oberfläche zu überlassen.  </para>

<para
>&kappname; ist eine grafische Oberfläche für Profiling-Daten und erfüllt all diese Wünsche. Obwohl das Programm ursprünglich programmiert wurde, um die Daten von &cachegrind; und &calltree; anzuzeigen, gibt es auch Konverter, mit denen sich Daten anderer Profiling-Werkzeuge anzeigen lassen. Im Anhang finden Sie auch eine Beschreibung des Datenformats von &cachegrind;/&callgrind;. </para>

<para
>Neben einer Liste der Funktionen sortiert nach exklusiven und inklusiven Kosten, optional gruppiert nach Quelldatei, Bibliothek oder C++-Klasse, unterstützt &kappname; mehrere Ansichten einer ausgewählten Funktion. Im Einzelnen sind dies: <itemizedlist>
<listitem
><para
>eine Aufruf-Diagramm-Ansicht, die den Bereich des Aufruf-Diagramms um die gewählte Funktion darstellt,</para>
</listitem>
<listitem
><para
>eine Baumansicht, die die Beziehungen eingebetteter Aufrufe zueinander darstellt, (mit den inklusiven Kosten zur schnellen Ermittlung problematischer Funktionen),</para>
</listitem>
<listitem
><para
>eine Quellcode- und Disassembler-Ansicht, die Details zu den Kosten einzelner Quelltextzeilen und Assembler-Anweisungen darstellt.</para>
</listitem>
</itemizedlist>

</para>
</sect1>
</chapter>

<chapter id="using-kcachegrind">
<title
>&kcachegrind; verwenden</title>

<sect1 id="using-profile">
<title
>Visualisierungsdaten erheben</title>

<para
>Als erstes muss man Geschwindigkeitsdaten erzeugen, indem man bestimmte Laufzeit-Eigenschaften eines Programms mit einem Profiling-Werkzeug misst. &kcachegrind; selbst enthält kein Profiling-Werkzeug, kann aber gut mit &callgrind; zusammenarbeiten. Wenn man einen Konverter einsetzt, kann man auch die von &oprofile; erzeugten Profiler-Daten visualisieren. Eine Erklärung der genauen Bedienung dieser Programme würde den Rahmen dieses Handbuchs sprengen; jedoch erhalten Sie dennoch im folgenden Kapitel eine kurze Schnellstart-Einführung. </para>

<sect2>
<title
>&callgrind;</title>

<para
>&callgrind; ist ein Bestandteil von &valgrind;, <ulink url="http://valgrind.org"
>http://valgrind.org</ulink
>. Früher hieß das Programm &calltree;, der Name war jedoch sehr irreführend. </para>

<para
>Die häufigste Verwendung von <application
>valgrind --tool=callgrind</application
> ist, indem man es dem zu messenden Programm auf der Befehlszeile voranstellt. Beispiel: <blockquote
><para
><command
>valgrind --tool=callgrind meinprogramm parameter</command
></para
></blockquote
>Beim Programmende wird die Datei <filename
>callgrind.out.pid</filename
> erzeugt, die Sie dann in &kcachegrind; laden können. </para>

<para
>Eine fortgeschrittenere Methode ist es, Profiling-Daten immer nur dann zu erzeugen, wenn eine bestimmte Funktion Ihres Programms aufgerufen wird. Wenn Sie beispielsweise für <command
>konqueror</command
> die Profiling-Daten zum Rendern einer Webseite erzeugen möchten, könnten Sie Daten erheben, wenn der Menüeintrag Ansicht/Aktualisieren benutzt wird (dies ist gleichzusetzen mit einem Aufruf von <symbol
>KonqMainWindow::slotReload</symbol
>). Benutzen Sie dazu den folgenden Aufruf: <blockquote
><para
><command
>valgrind --tool=callgrind --dump-before=KonqMainWindow::slotReload konqueror</command
></para
></blockquote
> Dadurch werden mehrere Profiler-Dateien erzeugt, jede mit einer eindeutigen, aufsteigenden Nummer im Dateinamen. Es wird auch eine Datei ohne aufsteigende Nummer erzeugt; wenn Sie diese in &kcachegrind; laden, werden die Folgedateien auch geladen und können in der Komponenten-Übersicht und Komponenten-Liste betrachtet werden. </para>

</sect2>

<sect2>
<title
>&oprofile;</title>

<para
>&oprofile; finden Sie unter <ulink url="http://oprofile.sf.net"
>http://oprofile.sf.net</ulink
>. Folgen Sie der Installationsanleitung auf der Webseite. Bevor Sie dies allerdings tun, prüfen Sie, ob das Programm nicht bereits von Ihrer Distribution mitgeliefert wird (so &eg; bei SuSE). </para>

<para
>Systemweites Profiling ist nur dem Systemverwalter erlaubt, da so alle Aktionen im System überwacht werden können. Die folgenden Schritte müssen Sie also als Systemverwalter ausführen. Richten Sie zuerst den Profiling-Prozess ein; mit der &GUI; <command
>oprof_start</command
> oder mit dem Befehlszeilenprogramm opcontrol. Timer-Modus (TBS, siehe Einführung) sollte voreingestellt sein. Um die Messung zu starten, führen Sie <command
>opcontrol -s</command
> aus. Starten Sie nun die Anwendung an deren Werten Sie interessiert sind und führen anschließend <command
>opcontrol -d</command
> aus. Die Messergebnisse werden in Dateien im Ordner <filename
>/var/lib/oprofile/samples/</filename
> gespeichert. Um die Daten zu betrachten, führen Sie <blockquote
><para
><command
>opreport -gdf | op2callgrind</command
></para
></blockquote
> in einem leeren Ordner aus. Es wird für jedes auf dem Systen laufende Programm eine Datei angelegt, die für sich in &kcachegrind; geöffnet werden kann. </para>

</sect2>
</sect1>

<sect1 id="using-basics">
<title
>Grundlagen der Benutzerschnittstelle</title>

<para
>Wenn Sie &kcachegrind; mit einer Profildaten-Datei als Argument starten, oder nachdem Sie über <menuchoice
><guimenu
>Datei</guimenu
> <guimenuitem
>Öffnen</guimenuitem
> </menuchoice
> eine Datei geöffnet haben, sehen Sie ein Navigationspanel mit der Liste der Funktionen links und dem Hauptbereich rechts, in dem die ausgewählte Funktion dargestellt wird. Dieser Darstellungsbereich kann so eingerichtet werden, dass er mehrere Darstellungsarten kombiniert. </para>

<para
>Beim ersten Start ist dieser Bereich in einen oberen und einen unteren Abschnitt unterteilt, in denen jeweils verschiedene Darstellungsarten ausgewählt werden können. Verwenden Sie das Kontextmenü der Unterfenster und passen Sie die Aufteilung Ihren Wünschen an. Um zwischen verschiedenen Darstellungsarten zu wechseln, verwenden Sie <quote
>Ansicht -> Layout ->Kopieren</quote
>, ändern das Layout und wechseln mit <quote
>Ansicht -> Layout -> Nächstes Layout</quote
> zwischen den Layouts. Sie können auch den dazugehörigen Kurzbefehl verwenden. </para>

<para
>Der aktuelle Ereignistyp ist wichtig für die Darstellung: Für &callgrind; ist das zum Beispiel <quote
>Cache Misses</quote
> oder <quote
>Cycle Estimation</quote
>; für &oprofile; im einfachsten Fall <quote
>Timer</quote
>. Sie können den Ereignistyp mit dem Kombinationsfeld in der Werkzeugleiste oder in der Ereignistyp-Ansicht ändern. Wenn Sie die Funktion <symbol
>main</symbol
> wählen und einen Blick auf den Aufruf-Graphen werfen, sehen Sie einen ersten Überblick über die Laufzeit-Charakteristik. Sie sehen dort die Aufrufe, die von Ihrem Programm getätigt wurden. Beachten Sie, dass die Aufruf-Graph-Ansicht nur Funktionen anzeigt, die eine hohe Anzahl Ereignisse aufweisen. Wenn Sie im Aufruf-Graphen auf eine Funktion klicken, werden die aufgerufenen Funktionen um die ausgewählte herum angezeigt. </para>

<para
>Um die &GUI; besser kennen zu lernen, lesen Sie zusätzlich zu diesem Handbuch auch den Dokumentationsabschnitt auf der Webseite <ulink url="http://kcachegrind.sf.net"
>http://kcachegrind.sf.net</ulink
>. Zudem hat jedes Element in &kcachegrind; eine <quote
>Was ist das</quote
>-Hilfe. </para>
</sect1>

</chapter>


<chapter id="kcachegrind-concepts">
<title
>Grundlegende Konzepte</title>

<para
>Dieses Kapitel erläutert einige in &kcachegrind; verwendete Konzepte und Begriffe aus der Bedienungsoberfläche. </para>

<sect1 id="concepts-model">
<title
>Das Datenmodell der Profildaten</title>

<sect2>
<title
>Kosteneinheiten</title>

<para
>Kosten von Ereignistypen (wie L2-Misses) sind Kostenpunkten zugeordnet, was Elemente mit Bezugspunkten im Quelltext oder in Datenstrukturen eines gegebenen Programms sind. Kostenpunkte können nicht nur einfache Positionen im Quelltext oder in Daten sein, sondern auch Positions-Tupel. Ein Aufruf, zum Beispiel, hat eine Quelle und ein Ziel, und eine Datenadresse kann einen Datentyp und eine Adresse im Quelltext haben, an der er alloziert wird. </para>

<para
>&kcachegrind; sind die wie folgt genannten Kostenpunkte bekannt. Einfache Positionen: <itemizedlist
> <listitem
><para
>Instruktion. Eine Assembler-Instruktion an einer bestimmten Adresse.</para
></listitem
> <listitem
><para
>Quelltextzeile einer Funktion. Alle Instruktionen, die der Compiler (über Debug-Informationen) einer Quelltextzeile zuordnet (Dateiname und Zeilennummer) und die im Kontext einer Funktion ausgeführt werden. Letzteres ist wichtig, da eine Zeile innerhalb einer Inline-Funktion im Kontext verschiedener Funktionen auftauchen kann. Instruktionen ohne Zuordnung erscheinen mit Zeilennummer 0 in Datei <quote
>???</quote
>.</para
></listitem
> <listitem
><para
>Funktion. Alle Quelltextzeilen einer Funktion. Eine Funktion wird über ihren Namen und, sofern vorhanden, ihre Position in einem Binärobjekt angegeben. Letzteres ist wichtig, da jedes Binärobjekt eines Programms Funktionen mit demselben Namen enthalten kann (auf diese kann &eg; mit dlopen/dlsym zugegriffen werden; der Laufzeit-Linker löst Funktionen in verwendeten Binärobjekten in einer bestimmten Suchreihenfolge auf). Wenn ein Profiling-Werkzeug den Symbolnamen einer Funktion nicht bestimmen kann, &eg; weil keine Debug-Informationen verfügbar sind, wird entweder die Adresse der zuerst ausgeführten Instruktion, oder <quote
>???</quote
> angegeben.</para
></listitem
> <listitem
><para
>Binärobjekt. Alle Funktionen, die innerhalb der Grenzen eines gegebenen Binärobjekts liegen. Dies gilt für die primäre Programmdatei, sowie für Shared-Libraries.</para
></listitem
> <listitem
><para
>Quelltextdatei. Alle Funktionen, deren erste Instruktion einer Zeile der gegebenen Quelltextdatei zugeordnet ist.</para
></listitem
> <listitem
><para
>Klasse. Symbolnamen von Funktionen sind normalerweise hierarchisch in Namensräumen geordnet, &eg; C++-Namensräume, oder Klassen in objektorientierten Sprachen; daher kann eine Klasse selbst Funktionen der Klasse und eingebetteter Klassen enthalten.</para
></listitem
> <listitem
><para
>Profilabschnitt. Ein Zeitabschnitt eines Profiler-Durchlaufs mit einem gegebenen Thread-ID, Prozess-ID und ausgeführter Befehlszeile.</para
></listitem
> </itemizedlist
> Wie Sie an der Liste erkennen können, definiert ein Satz Kostenpunkte oft einen neuen Kostenpunkt; daher entsteht eine Einrechnungshierarchie von Kostenpunkten, die durch die obige Beschreibung ersichtlich sein sollte. </para>

<para
>Positions-Tupel: <itemizedlist
> <listitem
><para
>Aufruf von Instruktionsadresse auf Zielfunktion.</para
></listitem
> <listitem
><para
>Aufruf von Quelltextzeile auf Zielfunktion.</para
></listitem
> <listitem
><para
>Aufruf von Quellfunktion auf Zielfunktion.</para
></listitem
> <listitem
><para
>(Un)bedingter Sprung von Quellinstruktion auf Zielinstruktion.</para
></listitem
> <listitem
><para
>(Un)bedingter Sprung von Quellzeile auf Zielzeile.</para
></listitem
> </itemizedlist
> Sprünge zwischen Funktionen werden nicht unterstützt, da diese in einem Aufrufgraphen nicht sinnvoll sind; daher müssen Konstruktionen wie Ausnahmen (Exceptions) und Long-Jumps in C so verändert werden, dass sie, sofern nötig, als Pop-Instruktion auf den Aufrufstapel ausgeführt werden. </para>

</sect2>



<sect2>
<title
>Ereignistypen</title>

<para
>In den Profildaten können weitere Ereignistypen angegeben werden, indem ihnen ein Name zugeordnet wird. Ihre Kosten bezogen auf einen Kostenpunkt ist ein 64-Bit-Integer. </para>
<para
>Ereignistypen, deren Kosten in einer Profildaten-Datei angegeben sind, heißen <quote
>echte Ereignisse</quote
>. Zusätzlich können Sie Formeln für Ereignistypen definieren, die aus echten Ereignissen errechnet werden. Diese heißen abgeleitete Ereignisse. </para>
</sect2>

</sect1>

<sect1 id="concepts-state">
<title
>Darstellungsstatus</title>

<para
>Der Darstellungsstatus eines &kcachegrind;-Fensters beinhaltet: <itemizedlist
> <listitem
><para
>den anzuzeigenden primären und sekundären Ereignistyp,</para
></listitem
> <listitem
><para
>die Funktionsgruppierung (für die Funktionsprofil-Liste und die Einfärbung der Elemente),</para
></listitem
> <listitem
><para
>die Abschnitte des Profils, die in die Darstellung eingehen</para
></listitem
> <listitem
><para
>ein aktiver Kostenpunkt (&eg; eine Funktion, die aus der Funktionsprofil-Ansicht ausgewählt wurde),</para
></listitem
> <listitem
><para
>ein ausgewählter Kostenpunkt.</para
></listitem
> </itemizedlist
> Dieser Status beeinflusst die Darstellung. </para>
<para
>Ein Kostenpunkt (der aktive) wird immer dargestellt. Ist eine Darstellung nicht angemessen für einen Kostenpunkt, wird sie ausgeblendet (&eg; wenn ein &ELF;-Objekt aus der Gruppenliste ausgewählt wird, sind Anmerkungen am Quelltext nicht sinnvoll). </para>
<para
>Zum Beispiel zeigt die Aufgerufene-Liste einer aktiven Funktion alle Funktionen, die auf der aktiven heraus aufgerufen wurden. Sie können eine dieser Funktionen markieren, ohne sie zu aktivieren. Wird der Aufruf-Graph daneben angezeigt, wird hier automatisch die gleiche Funktion ausgewählt. </para>

</sect1>

<sect1 id="concepts-guiparts">
<title
>Bestandteile der Benutzeroberfläche</title>

<sect2>
<title
>Navigationsbereich</title>
<para
>Docks sind Seitenfenster, die an jeder Seite des &kcachegrind;-Fensters angebracht werden können. Sie enthalten jeweils eine Liste mit Kostenpunkten in einer bestimmten Ordnung. <itemizedlist>
<listitem
><para
>Funktionsprofil. Das Funktionsprofil ist eine Liste von Funktionen, in der die Inklusiv- und Exklusivkosten, die Anzahl der Aufrufe, der Name und die Position der Funktionen angezeigt werden. </para
></listitem>
<listitem
><para
>Übersicht der Profilabschnitte </para
></listitem>
<listitem
><para
>Aufrufstapel </para
></listitem>
</itemizedlist>
</para>
</sect2>

<sect2>
<title
>Darstellungsbereich</title>
<para
>Der Darstellungsbereich, gewöhnlich der rechte Bereich im &kcachegrind;-Hauptfenster, ist aus einem (Standard), oder mehreren Unterfenstern aufgebaut, die entweder waagerecht oder senkrecht angeordnet sind. Jedes Unterfenster enthält verschiedene Darstellungsansichten, die jeweils immer einen Kostenpunkt anzeigen. Der Name dieses Kostenpunkts wird oben in der Unterfensteransicht angezeigt. Sind mehrere Unterfensteransichten vorhanden, ist immer nur eine von ihnen aktiv. Der Name des Kostenpunkts wird im aktiven Unterfenster fett dargestellt und bestimmt den aktiven Kostenpunkt im &kcachegrind;-Fenster. </para>
</sect2>

<sect2>
<title
>Bereiche einer Unterfensteransicht</title>
<para
>Jede Unterfensteransicht kann bis zu vier Bereiche enthalten, oben, rechts, links und unten. Zudem kann jeder Bereich mehrere Darstellungsansichten enthalten. Die anzuzeigende Ansicht eines Bereichs wird über die Unterfensterleiste ausgewählt. Die Unterfensterleisten der oberen und rechten Bereiche befindet sich oben; die der linken und unteren Bereiche befinden sich unten. Sie können festlegen, welche Darstellungsart in welchem Bereich angezeigt wird, indem Sie das Kontextmenü des Unterfensters verwenden. </para>
</sect2>

<sect2>
<title
>Darstellungsabgleich über ausgewähltes Element in einer Unterfensteransicht</title>
<para
>Neben einem aktiven Element hat jede Unterfensteransicht ein ausgewähltes Element. Da die meisten Darstellungsarten mehrere Elemente anzeigen, wobei das aktive irgendwie zentriert wird, können Sie das gewählte Element ändern, indem Sie in der Darstellung navigieren (mit Mausklick oder der Tastatur). Ausgewählte Elemente werden hervorgehoben. Wenn Sie die Auswahl in einer Darstellung ändern, wird die Hervorhebung in allen anderen Darstellungen ebenfalls geändert. </para>
</sect2>

<sect2>
<title
>Abgleich zwischen Unterfensteransichten</title>
<para
>Sind mehrere Unterfensteransichten vorhanden, ändert eine Auswahländerung in einer Ansicht eine Aktivitätsänderung in der nächsten Ansicht. Diese Verknüpfung ermöglicht eine schnelle Navigation in Aufruf-Graphen. </para>
</sect2>

<sect2>
<title
>Layouts</title>
<para
>Das Layout aller Unterfensteransichten eines Fensters kann gespeichert werden (siehe Menüpunkt <quote
>Ansicht -> Layout</quote
>). Nach dem Kopieren des aktuellen Layouts (&Ctrl;+Plus oder im Menü) und Ändern einiger Größen oder Verschieben einer Darstellungsansicht in einen anderen Bereich einer Unterfensteransicht können Sie mit &Ctrl;+Pfeil links bzw. &Ctrl;+Pfeil rechts zwischen dem alten und dem neuen Layout umschalten. Die Layouts werden über &kcachegrind;-Sitzungen mit dem gleichen Profiler-Befehl hinweg gespeichert. Sie können die aktuellen Layouts als Voreinstellung für neue Sitzungen speichern, oder das Standard-Layout wiederherstellen. </para>
</sect2>
</sect1>

<sect1 id="concepts-sidedocks">
<title
>Navigationsbereich</title>

<sect2>
<title
>Flaches Profil</title>
<para
>Das flache Profil enthält eine Gruppenliste und eine Funktionsliste. Die Gruppenliste zeigt alle Gruppen, in denen Kosten verursacht werden, abhängig vom gewähten Gruppentyp. Die Gruppenliste ist ausgeblendet, wenn die Gruppierung ausgeschaltet ist. </para>
<para
>Die Funktionsliste enthält die Funktionen der gewählten Gruppe (oder alle Funktionen, wenn die Gruppierung abgeschaltet ist), sortiert nach Spalten, &eg; Inklusiv- oder Exklusivkosten. Die Anzahl der Elemente in der Liste ist begrenzt, und kann unter <quote
>Einstellungen -> &kcachegrind; einrichten</quote
> angepasst werden. </para>
</sect2>

<sect2>
<title
>Übersicht der Profilabschnitte</title>
<para
>Während eines Profiler-Durchlaufs können mehrere Profildaten-Dateien erzeugt werden, die alle zusammen in &kcachegrind; geladen werden können. Das Dock <quote
>Übersicht der Profilabschnitte</quote
> zeigt diese an, waagerecht angeordnet nach Erstellungszeit. Die Größen der Rechtecke sind proportional zu den Kosten der Abschnitte. Sie können einen oder mehrere Abschnitte auswählen um die Anzeige der Kosten in den anderen &kcachegrind;-Ansichten auf diese Abschnitte zu beschränken. </para>
<para
>Die Abschnitte sind weiter unterteilt: es gibt einen Partitions- und einen Inklusivkosten-Modus: <itemizedlist>
<listitem
><para
>Detailansicht: Sie sehen die Aufteilung der Dateien eines Profildaten-Abschnitts in Gruppen, je nachdem, welcher Gruppentyp ausgewählt ist. Sind zum Beispiel &ELF;-Objektgruppen ausgewählt, sehen Sie farbige Rechtecke für jedes benutze &ELF;-Objekt (Shared-Library oder Programmdatei), deren Größe durch die verursachten Kosten bestimmt wird. </para
></listitem>
<listitem
><para
>Aufteilung der Inklusivkosten: Es wird ein Rechteck mit den Inklusivkosten der aktiven Funktion angezeigt. Dieses ist wiederum in die Inklusivkosten der aufgerufenen Funktionen unterteilt. </para
></listitem>
</itemizedlist>
</para>
</sect2>

<sect2>
<title
>Aufrufstapel</title>
<para
>Dieser Aufrufstapel ist nicht echt sondern ein <quote
>sehr wahrscheinliches</quote
> Abbild. Er wird von der aktiven Funktion her aufgebaut und enthält alle Aufrufer/Aufgerufenen absteigend mit den höchten Kosten oben. </para>
<para
>Die Spalten 'Kosten' und 'Aufrufe' zeigen die Kosten aller Aufrufe der Funktion eine Zeile höher. </para>
</sect2>
</sect1>

<sect1 id="concepts-visualizations">
<title
>Darstellungen</title>

<sect2>
<title
>Ereignistypen</title>
<para
>Diese Liste zeigt alle verfügbaren Kostentypen und die dazugehörigen Exklusiv- und Inklusivkosten der aktuell aktiven Funktion für den Ereignistyp. </para>
<para
>Wenn Sie einen Ereignistyp wählen, ändern Sie den Kostentyp, der überall in &kcachegrind; angezeigt wird. </para>
</sect2>

<sect2>
<title
>Aufruflisten</title>
<para
>Diese Listen zeigen Aufrufe auf/von der derzeit aktiven Funktion. <quote
>Alle</quote
> Aufrufer/Aufgerufene bedeutet, dass diese Funktionen in Richtung vom Aufrufer zum Aufgerufenen erreichbar sind, selbst wenn andere Funktionen dazwischen stehen. </para>
<para
>Die Ansicht von Aufruflisten enthält: <itemizedlist>
<listitem
><para
>Direkte Aufrufer </para
></listitem>
<listitem
><para
>Direkt Aufgerufene </para
></listitem>
<listitem
><para
>Alle Aufrufer </para
></listitem>
<listitem
><para
>Alle Aufgerufenen </para
></listitem>
</itemizedlist>
</para>
</sect2>

<sect2>
<title
>Karten</title>
<para
>Eine Baumstruktur-Darstellung des primären Ereignistyps, auf- oder abwärts in der Aufrufhierarchie. Jedes farbige Rechteck stellt eine Funktion dar; die Größe ist (abgesehen von zeichnerischen Ungenauigkeiten) proportional zu den verursachten Kosten, während die aktive Funktion ausgeführt wird. </para>
<para
>In der Aufruferkarte zeigt der Graph die eingebettete Hierarchie aller Aufrufer der aktiven Funktion; in der Aufrufkarte werden alle Aufgerufenen der aktiven Funktion angezeigt. </para>
<para
>Einstellungen zum Erscheinungsbild finden Sie im Kontextmenü. Wählen Sie <quote
>Ungenaue Ränder ausblenden</quote
> um genaue Größen-Proportionen zu bekommen. Da diese Funktion sehr zeitintensiv sein kann, ist es ratsam, die maximale Verschachtelungstiefe zu begrenzen. <quote
>Beste Teilungsrichtung pro Ebene</quote
> bestimmt die Teilungsrichtung anhand des Seitenverhältnisses des übergeordneten Elements. <quote
>Immer beste Teilungsrichtung</quote
> entscheidet anhand des verbleibenden Platzes für jedes Geschwister. <quote
>Proportionen ignorieren</quote
> nutzt den Platz zuerst für die Funktionsbeschriftung. Beachten Sie, dass das Größenverhältnis stark abweichen kann. </para>
<para
>Tastatursteuerung ist mit der linken und rechten Pfeiltaste möglich, um die Geschwister zu durchlaufen, und mit den Tasten Pfeil hoch/runter, um Verschachtelungebenen hoch bzw. runter zu gehen. Die Eingabetaste aktiviert das aktuelle Element. </para>
</sect2>

<sect2>
<title
>Aufrufgraph</title>
<para
>Diese Ansicht zeigt den Aufrufgraph um die aktive Funktion herum an. Die angezeigten Kosten sind nur die Kosten, die bei der Ausführung der Funktion angefallen sind; &ie; die Kosten für main(), sofern angezeigt, sollten den Kosten der aktiven Funktion entsprechen, da diese ein Teil der Inklusivkosten von main() sind, die bei der Ausführung der aktiven Funktion angefallen sind. </para>
<para
>Für Zyklen wird ein blauer Pfeil angezeigt, der angibt, dass es sich nicht um einen echten Aufruf handelt; er wurde zum richtigen Zeichnen eingefügt, wird aber nie ausgeführt. </para>
<para
>Ist der Graph größer als der Zeichenbereich, wird in einer Ecke eine Übersicht angezeigt. Es gibt ähnliche Darstellungen für die Aufruf-Baumansicht; die ausgewählte Funktion ist hervorgehoben. </para>
</sect2>

<sect2>
<title
>Code-Kommentierung</title>
<para
>Die kommentierten Quelltext/Assembler-Listen zeigen die Quelltextzeilen bzw. disassemblierten Instruktionen der aktiven Funktion zusammen mit den (Exklusiv)-Kosten, die beim Ausführen der Quelltextzeile/Instruktion verursacht wurden. Im Falle eines Aufrufs werden Zeilen mit Details zum Aufruf in den Quelltext eingefügt: (Inklusiv)-Kosten innerhalb des Aufrufs, Anzahl der Aufrufe und Aufrufziel. </para>
<para
>Wählen Sie so eine Aufrufinformationslinie, um das Aufrufziel zu aktivieren. </para>
</sect2>
</sect1>

</chapter>


<chapter id="commands">
<title
>Befehlsreferenz</title>

<sect1 id="kcachegrind-mainwindow">
<title
>Das Hauptfenster von &kcachegrind;</title>

<sect2>
<title
>Das Menü <guimenu
>Datei</guimenu
></title>
<para>
<variablelist>

<varlistentry>
<term
><menuchoice
><shortcut
> <keycombo
>&Ctrl;<keycap
>N</keycap
></keycombo
> </shortcut
> <guimenu
>Datei</guimenu
> <guimenuitem
>Neu</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Öffnet ein leeres Hauptfenster, in das Sie Profildaten laden können.</action
> Diese Aktion wird eigentlich nicht benötigt, da <menuchoice
><guimenu
>Datei</guimenu
> <guimenuitem
>Öffnen ....</guimenuitem
> </menuchoice
> ein neues Hauptfenster öffnet, wenn im aktuellen Fenster bereits Daten angezeigt werden. </para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><shortcut
> <keycombo
>&Ctrl;<keycap
>O</keycap
></keycombo
> </shortcut
> <guimenu
>Datei</guimenu
> <guimenuitem
>Öffnen ...</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Öffnet den "Datei öffnen"-Dialog zur Auswahl der zu ladenden Profildaten-Datei.</action
> Wenn im aktuellen Fenster bereits Daten angezeigt werden, wird ein neues Hauptfenster geöffnet. Zum hinzufügen zusätzlicher Profildaten im aktuellen Fenster, verwenden Sie <menuchoice
><guimenu
>Datei</guimenu
> <guimenuitem
>Hinzufügen ...</guimenuitem
> </menuchoice
>. </para>
<para
>Der Name von Profildaten-Dateien endet normalerweise auf <quote
>.pid.part-threadID</quote
>, wobei <quote
>part</quote
> und <quote
>threadID</quote
> optional sind und <quote
>pid</quote
> und <quote
>part</quote
> für mehrere Profildaten-Dateien eines einzelnen Programmdurchlaufs verwendet werden. Wenn Sie eine Datei mit der Endung <quote
>.pid</quote
> öffnen, werden vorhandene Daten-Dateien desselben Durchlaufs automatisch geladen. </para>
<para
>Beispiel: Existieren die Profildatendateien cachegrind.out.123 und cachegrind.out.123.1, wird beim Laden der ersten Datei automatisch die zweite Datei mit geladen. </para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><guimenu
>Datei</guimenu
> <guimenuitem
>Hinzufügen ...</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Fügt im aktuellen Fenster eine Profildaten-Datei hinzu.</action
> Hiermit können Sie das Laden mehrerer Daten-Dateien in einem Hauptfenster erzwingen, obwohl diese nicht aus demselben Durchlauf stammen, also nicht den Namenskonventionen für Profildaten-Dateien entsprechen. Das ist vor allem zum Direktvergleich einsetzbar. </para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><guimenu
>Datei</guimenu
> <guimenuitem
>Neu laden</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Profildaten neu laden.</action
> Dies ist vor allem dann sinnvoll, wenn eine neue Profildaten-Datei für eine bereits geladene Anwendung erzeugt wird. </para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><shortcut
><keycombo action="simul"
>&Ctrl;<keycap
>Q</keycap
></keycombo
> </shortcut
><guimenu
>Datei</guimenu
><guimenuitem
>Beenden</guimenuitem
>  </menuchoice
></term>
<listitem
><para
><action
>Beendet</action
> &kappname;</para
></listitem>
</varlistentry>
</variablelist>
</para>

</sect2>

<sect2>
<title
>Das Menü <guimenu
>Ansicht</guimenu
></title>
<para>
<variablelist>

<varlistentry>
<term
><menuchoice
><guimenu
>Ansicht</guimenu
> <guisubmenu
>Erster Ereignistyp</guisubmenu
> </menuchoice
></term>
<listitem
><para
><action
>Noch zu schreiben</action
></para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><guimenu
>Ansicht</guimenu
> <guisubmenu
>Zweiter Ereignisyp</guisubmenu
> </menuchoice
></term>
<listitem
><para
><action
>Noch zu schreiben</action
></para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><guimenu
>Ansicht</guimenu
> <guimenuitem
>Gruppierung</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Noch zu schreiben</action
></para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><guimenu
>Ansicht</guimenu
> <guimenuitem
>Layout</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Noch zu schreiben</action
></para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><guimenu
>Ansicht</guimenu
> <guimenuitem
>Teilen</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Noch zu schreiben</action
></para
></listitem>
</varlistentry>

</variablelist>
</para>

</sect2>


</sect1>
</chapter>

<chapter id="faq">
<title
>Fragen und Antworten</title>
&reporting.bugs; &updating.documentation; <qandaset id="faqlist">


<qandaentry>
<question>
<para
>Wozu ist &kcachegrind; gut? </para>
</question>
<answer>
<para
>&kcachegrind; ist nützlich für die späte Software-Entwicklungs-Etappe Profiling. Wenn man keine Anwendungen entwickelt, dann braucht man &kcachegrind; nicht. </para>
</answer>
</qandaentry>

<qandaentry>
<question>
<para
>Was ist der Unterschied zwischen ‚Incl.‘ und ‚Self‘? </para>
</question>
<answer>
<para
>Dies sind Kosteneigenschaften für Funktionen hinsichtlich einiger Ereignistypen. Da sich Funktionen gegenseitig aufrufen können, ist es sinvoll, zwischen Kosten zu unterscheiden, die die Funktion selbst verursacht (Exklusivkosten) und solchen, die alle aufgerufenen Funktionen berücksichtigt (Inklusivkosten). </para>
<para
>Also werden Sie für main() immer Inklusivkosten von nahezu 100 % haben, wogegen die Exlusivkosten vernachlässigbar sind, wenn die eigentliche Arbeit in einer anderen Funktion erledigt wird. </para>
</answer>
</qandaentry>

<qandaentry>
<question>
<para
>Die Werkzeugleiste/Menüleiste ist bei mir sehr spartanisch. Ist das normal?</para>
</question>
<answer>
<para
>Ihre &kcachegrind;-Installation ist fehlerhaft. Es wird empfohlen, das Programm mit Installationspräfix-Pfad Ihrer systemweiten KDE-Installation zu übersetzen, &eg; <command
>configure --prefix=/opt/kde4; make install</command
>. Wenn Sie einen anderen Ordner, &eg; $HOME/kde, wählen, müssen Sie die Umgebungsvariable KDEDIR auf diesen Ordner setzen, bevor Sie &kcachegrind; ausführen. </para>
</answer>
</qandaentry>

<qandaentry>
<question>
<para
>Wenn ich in der Aufrufgraph-Ansicht auf eine Funktion klicke, werden für main() die gleichen Kosten angezeigt, wie für die gewählte Funktion. Sollten diese nicht immer 100 % betragen? </para>
</question>
<answer>
<para
>Sie haben eine Funktion unterhalb von main() gewählt, die geringere Kosten als main() hat. Für jede Funktion wird nur der Teil der Gesamtkosten angezeigt, der von der aktivierten Funktion verursacht wird. Daher können die Kosten für eine Funktion nie höher sein als die der aktivierten Funktion. </para>
</answer>
</qandaentry>


</qandaset>
</chapter>

<chapter id="glossary">
<title
>Glossar</title>

<para
>Es folgt eine unsortierte Liste mit einigen Begriffserklärungen. <itemizedlist>
<listitem
><para
>Profiling: Der Prozess des Sammelns statistischer Informationen über die Laufzeit-Eigenschaften eines Programmablaufs. </para
></listitem>
<listitem
><para
>Tracing: Der Prozess des Überwachens eines Programmaufrufs. Dabei werden auftretende Ereignisse nach Zeitstempeln sortiert in eine Datei geschrieben, die Profildatendatei. </para
></listitem>
<listitem
><para
>Profildaten: Eine Abfolge zeitlich markierter Ereignisse, die beim Überwachen eines Programmablaufs aufgetreten sind. Die Datenmenge verhält sich normalerweise linear zu Laufzeit des Programms. </para
></listitem>
<listitem
><para
>Profildatendatei: Eine Datei mit Daten, die Messwerte eines Profile-Experiments (oder eines Abschnitts davon) enthält oder beim Nachverarbeiten von Profildaten erzeugt wurde. Die Datenmenge verhält normalerweise linear zur Größe des Quelltextes. </para
></listitem>
<listitem
><para
>Profildaten-Schnipsel: Daten aus einer Profildaten-Datei. </para
></listitem>
<listitem
><para
>Profile-Experiment: Ein Programmablauf, der von einem Profiling-Werkzeug überwacht wird und eine oder mehrere Profildaten-Dateien aus Abschnitten und/oder Threads des Ablaufs erzeugt. </para
></listitem>
<listitem
><para
>Profile-Projekt: Eine Konfiguration für Profile-Experimente, die für ein zu überwachendes Programm, vielleicht in mehreren Versionen, verwendet wird. Profildaten zu vergleichen, ist nur dann sinnvoll, wenn sie in Experimenten eines Profile-Projekts erzeugt wurden. </para
></listitem>
<listitem
><para
>Kostenpunkt: Abstraktes Element mit Bezug zu Stellen im Quelltext denen sich Ereigniszahlen zuordnen lassen. Kostenpunkte werden in den Maßen Position in Quelltext (&eg; Zeile, Funktion), Position der Daten (&eg; aufgerufene Datentypen, Datenobjekt), Ort der Ausführung (&eg; Thread, Prozess) und Tupel oder Tripel der genannten Positionen (&eg; Aufrufe, Zugriff auf Objekte, aus dem Cache entfernte Daten). </para
></listitem>
<listitem
><para
>Ereignistyp: Art eines Ereignisses, dessen Kosten einem Kostenpunkt zugeordnet werden können. Es gibt echte und abgeleitete Ereignistypen. </para
></listitem>
<listitem
><para
>Echte Ereignistypen: Ereignistyp, der mit einem entsprechenden Werkzeug gemessen werden kann. Es ist ein Sensor für den gegebenen Ereignistyp erforderlich. </para
></listitem>
<listitem
><para
>Abgeleiteter Ereignistyp: Virtueller Ereignistyp, der nur in Darstellungen angezeigt wird, die mit einer Formel aus einem echten Ereignistyp errechnet werden. </para
></listitem>
<listitem
><para
>Ereigniskosten: Summe der Ereignisse eines Ereignistyps, der während der Ausführung aufgetreten ist und zu einem bestimmten Kostenpunkt gehört. Die Kosten werden dem Punkt zugeordnet. </para
></listitem>
</itemizedlist>
</para>
</chapter>

<chapter id="credits">


<title
>Danksagungen und Lizenz</title>

<para
>&kappname; </para>
<para
>Dank an Julian Seward für seine einzigartige Anwendung &valgrind; und Nicholas Nethercote für den &cachegrind; Zusatz. Ohne diese Programme würde &kcachegrind; nicht existieren. Viele Ideen für die Benutzeroberfläche stammen ebenfalls von ihnen. </para>
<para
>Dank für die vielen Fehlerberichte/Vorschläge von verschiedenen Nutzern. </para>

<para
>Übersetzung Thomas Reitelbach <email
>tr@erdfunkstelle.de</email
></para
> 
&underFDL; </chapter>

<appendix id="installation">
<title
>Installation</title>

<sect1 id="getting-kcachegrind">
<title
>Bezugsquellen von &kcachegrind;</title>

<para
>&kcachegrind; ist Teil des &kde;-Paketes &package;.  Zusätzlich gibt es das Programm, &callgrind;, und weitere Dokumentation Sie auf der Webseite <ulink url="http://kcachegrind.sf.net"
> http://kcachegrind.sf.net</ulink
>. Dort gibt es weitere Installations- und Kompilierungshinweise. </para>
</sect1>

<sect1 id="requirements">
<title
>Anforderungen</title>

<para
>Um &kcachegrind; erfolgreich einsetzen zu können, benötigen Sie &kde; 4.x. Um die Ablaufprotokolle zu erzeugen, sind zusätzlich &cachegrind; oder &calltree;/&callgrind; erforderlich. </para>
</sect1>

<sect1 id="compilation">
<title
>Kompilierung und Installation</title>
&install.compile.documentation; </sect1>

<sect1 id="configuration">
<title
>Einrichtung</title>

<para
>Alle Einstellungsmöglichkeiten sind entweder im Einstellungsdialog oder in den Kontextmenüs der Graphen zu finden. </para>

</sect1>

</appendix>

&documentation.index;
</book>
<!--
Local Variables:
mode: sgml
sgml-minimize-attributes:nil
sgml-general-insert-case:lower
sgml-indent-step:0
sgml-indent-data:nil
End:
-->













