<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.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 EBS "<acronym
>EBS</acronym
>">
  <!ENTITY TBS "<acronym
>TBS</acronym
>">
  <!ENTITY % addindex "IGNORE">
  <!ENTITY % Slovenian "INCLUDE">
]>

<book id="kcachegrind" lang="&language;">

<bookinfo>
<title
>&kcachegrind; Priročnik</title>

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

<author
><firstname
>Federico</firstname
> <surname
>Zenith</surname
> <affiliation
> <address
><email
>federico.zenith@member.fsf.org</email
></address>
</affiliation>
<contrib
>Posodobitve in popravki</contrib>
</author>

<othercredit role="translator"
><firstname
>Matjaž</firstname
><surname
>Jeran</surname
><affiliation
><address
><email
>matjaz.jeran@amis.net</email
></address
></affiliation
><contrib
>Prevod</contrib
></othercredit
> 

</authorgroup>

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

<date
>18.11.2016</date>
<releaseinfo
>0.8.0 (aplikacije 17.04)</releaseinfo>

<abstract>
<para
>&kcachegrind; je orodje za vizualizacijo podatkov profila, napisano z uporabo &kde-frameworks;. </para>
</abstract>

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

</bookinfo>


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

<para
>&kcachegrind; je brskalnik za podatke, ki so jih ustvarila orodja za profiliranje. V tem poglavju je razloženo, čemu je namenjeno profiliranje, kako se izvaja in podaja nekaj primerov razpoložljivih orodij za profiliranje. </para>

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

<para
>Pri razvoju programa eden od zadnjih korakov pogosto vključuje optimizacijo delovanja. Ker redko uporabljenih funkcij nima smisla optimizirati, ker bi bila to izguba časa, je treba vedeti, v katerem delu programa se preživi največ časa. </para>

<para
>Za zaporedno kodo običajno zadostuje zbiranje statističnih podatkov o značilnostih izvajalnega časa programa, kot so številke časa, porabljenega v funkcijah in vrsticah kode. To se imenuje profiliranje. Program se izvaja pod nadzorom orodja za profiliranje, ki na koncu poda povzetek izvajanja. Nasprotno pa pri vzporedni kodi težave z zmogljivostjo običajno nastanejo, ko en procesor čaka na podatke drugega. Ker tega čakalnega časa običajno ni mogoče preprosto pripisati, je tukaj bolje ustvariti sledi dogodkov s časovnimi žigi. &kcachegrind; ne more vizualizirati te vrste podatkov. </para>

<para
>Po analizi ustvarjenih podatkov o profilu bi moralo biti enostavno videti vroče točke in ozka grla kode: preveriti je mogoče na primer predpostavke o številu klicev in optimizirati identificirana področja kode. Nato je treba uspešnost optimizacije preveriti z drugim zagonom profila. </para>
</sect1>

<sect1 id="introduction-methods">
<title
>Metode profiliranja</title>

<para
>Za natančno merjenje pretečenega časa ali beleženje dogodkov, ki se zgodijo med izvajanjem področja kode (&eg; funkcije), je treba pred in za danim območjem vstaviti dodatno kodo merjenja. Ta koda prebere čas ali globalno število dogodkov in izračuna razlike. Zato je treba prvotno kodo pred izvedbo spremeniti. To se imenuje instrumentacija. Instrumentacijo lahko izvede programer sam, prevajalnik ali izvajalni sistem. Ker so zanimiva območja običajno ugnezdena, režijski stroški merjenja vedno vplivajo na samo merjenje. Zato je treba instrumentacijo izvajati selektivno, rezultate pa je treba razlagati previdno. Seveda je zaradi tega analiza delovanja z natančnimi meritvami zelo zapleten proces.</para>

<para
>Natančne meritve so možne zaradi števcev strojne opreme (vključno s števci, ki se povečujejo ob časovnem tiku), ki so na voljo v sodobnih procesorjih in se povečajo vsakič, ko se zgodi dogodek. Ker želimo dogodke pripisati regijam kode, bi morali brez števcev vsak dogodek obravnavati tako, da sami povečamo števec za trenutno regijo kode. Izvajanje tega v programski opremi seveda ni mogoče; toda ob predpostavki, da je porazdelitev dogodkov po izvorni kodi podobna, če gledamo samo vsak n-ti dogodek namesto vsakega dogodka, je bila razvita merilna metoda, katere režijski stroški so nastavljivi: imenuje se vzorčenje. Časovno zasnovano vzorčenje (&TBS;) uporablja časovnik za redno pregledovanje programskega števca za ustvarjanje histograma nad programsko kodo. Vzorčenje na podlagi dogodkov (&EBS;) izkorišča števce strojne opreme sodobnih procesorjev in uporablja način, v katerem se obdelovalnik prekinitev kliče ob pretoku števca, da ustvari histogram ustrezne porazdelitve dogodkov: v upravljalniku se števec dogodkov vedno znova inicializira na <symbol
>n</symbol
> metode vzorčenja. Prednost vzorčenja je, da kode ni treba spreminjati, vendar je še vedno kompromis: zgornja predpostavka bo pravilnejša, če je <symbol
>n</symbol
> majhen, manjši pa kot je <symbol
>n</symbol
>, višji so stroški obdelovalnika prekinitev.</para>

<para
>Druga merilna metoda je simulacija stvari, ki se dogajajo v računalniškem sistemu pri izvajanju dane kode, &ie; simulacija, ki jo poganja izvajanje. Simulacija vedno izhaja iz bolj ali manj natančnega strojnega modela; pri zelo podrobnih modelih strojev, ki dajejo zelo blizu realnosti, pa je lahko čas simulacije v praksi nesprejemljivo visok. Prednost simulacije je, da je mogoče v dano kodo vstaviti poljubno zapleteno merilno/simulacijsko kodo brez motečih rezultatov. Izvajanje tega neposredno pred izvajanjem (imenovano instrumentacija izvajalnega časa) z uporabo izvirne binarne datoteke je zelo udobno za uporabnika: ponovno prevajanje ni potrebno. Simulacija postane uporabna, če simuliramo le dele stroja s preprostim modelom; druga prednost je, da so rezultati, ki jih ustvarijo preprosti modeli, pogosto lažje razumljivi: pogosto je težava z resnično strojno opremo v tem, da rezultati vključujejo prekrivajoče se učinke iz različnih delov stroja.</para>
</sect1>

<sect1 id="introduction-tools">
<title
>Orodja za profiliranje</title>

<para
>Najbolj znano je orodje za profiliranje GCC <application
>gprof</application
>: program je treba prevesti z možnostjo <option
>-pg</option
>; zagon programa generira datoteko <filename
>gmon.out</filename
>, ki jo je mogoče pretvoriti v človeku berljivo obliko z <command
>gprof</command
>. Ena pomanjkljivost je potreben korak ponovnega prevajanja za pripravo izvršljive datoteke, ki mora biti statično povezana. Tukaj uporabljena metoda je instrumentacija, ki jo ustvari prevajalnik, ki meri loke klicev, ki se dogajajo med funkcijami, in ustrezna števila klicev v povezavi z &TBS;, ki daje histogram časovne porazdelitve po kodi. Z uporabo obeh informacij je mogoče hevristično izračunati inkluzivni čas funkcij, &ie; čas, porabljen v funkciji, skupaj z vsemi funkcijami, ki so iz nje priklicane. </para>

<para
>Za natančno merjenje dogajanja obstajajo knjižnice s funkcijami, ki lahko preberejo števce zmogljivosti strojne opreme. Najbolj znan tukaj je popravek PerfCtr za &Linux; in arhitekturno neodvisni knjižnici PAPI in PCL. Kljub temu je za natančno merjenje potrebna instrumentacija kode, kot je navedeno zgoraj. Bodisi uporablja knjižnice same bodisi uporablja samodejne instrumentacijske sisteme, kot je ADAPTOR (za izvorne instrumente FORTRAN) ali DynaProf (vbrizgavanje kode prek DynInsta).</para>

<para
>&oprofile; je sistemsko orodje za profiliranje za &Linux; z uporabo vzorčenja. </para>

<para
>V mnogih pogledih je udoben način profiliranja uporaba &cachegrind; ali &callgrind;, ki sta simulatorja, ki uporabljata okvir izvajalnega instrumentarija &valgrind;. Ker ni potrebe po dostopu do števcev strojne opreme (kar je pogosto težko pri današnjih namestitvah &Linux;), binarne datoteke, ki jih želite profilirati, pa lahko pustite nespremenjene, je dobra alternativa drugim orodjem za profiliranje. Pomanjkljivost simulacije - upočasnitev - lahko zmanjšamo tako, da simulacijo izvajamo samo na zanimivih delih programa in morda le na nekaj ponovitvah zanke. Brez merilnih/simulacijskih instrumentov ima uporaba &valgrind; le faktor upočasnitve v razponu od 3 do 5. Poleg tega, ko sta zanimiva samo graf klicev in štetje klicev, lahko simulator predpomnilnika izklopite. </para>

<para
>Simulacija predpomnilnika je prvi korak pri približevanju realnega časa, saj je čas izvajanja zelo občutljiv na izkoriščanje tako imenovanih <emphasis
>predpomnilnikov</emphasis
>, majhnih in hitrih vmesnih pomnilnikov, ki pospešujejo ponavljajoče se dostope do istih glavnih pomnilniških celic v sodobnih sistemih. &cachegrind; izvaja simulacijo predpomnilnika z lovljenjem dostopov do pomnilnika. Proizvedeni podatki vključujejo število dostopov do pomnilnika ukazov/podatkov ter zgrešenih predpomnilnika prve in druge ravni ter jih povezujejo z izvornimi vrsticami in funkcijami zagnanega programa. Z združevanjem teh števila zamud in z uporabo zakasnitev tipičnih procesorjev je mogoče podati oceno porabljenega časa. </para>

<para
>&callgrind; je razširitev &cachegrind; ki sproti gradi graf klicev programa, &ie; kako se funkciji kličeta in koliko dogodkov se zgodi med izvajanjem funkcije. Poleg tega je mogoče podatke o profilu, ki jih je treba zbrati, ločiti po nitih in kontekstih verige klicev. Zagotovi lahko podatke o profiliranju na ravni navodil, da omogoči zaznamovanje razstavljene kode. </para>
</sect1>

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

<para
>Orodja za profiliranje običajno ustvarijo veliko količino podatkov. Želja po enostavnem brskanju navzdol in navzgor po grafu klicev, skupaj s hitrim preklapljanjem načina razvrščanja funkcij in prikazom različnih vrst dogodkov, motivira &GUI; aplikacijo za izpolnitev te naloge. </para>

<para
>&kcachegrind; je orodje za vizualizacijo podatkov profila, ki izpolnjuje te želje. Čeprav je bil najprej programiran z brskanjem po podatkih iz &cachegrind; in &calltree; v mislih so na voljo pretvorniki, ki lahko prikažejo podatke o profilu, ki jih ustvarijo druga orodja. V dodatku je opis datoteke &cachegrind;/&callgrind; podana oblika datoteke. </para>

<para
>Poleg seznama funkcij, razvrščenih glede na izključne ali vključujoče meritve stroškov in neobvezno razvrščenih glede na izvorno datoteko, knjižnico v skupni rabi ali razred C++, &kcachegrind; ponuja različne poglede za izbrano funkcijo, in sicer: <itemizedlist>
<listitem
><para
>pogled grafa klicev, ki prikazuje del grafa klicev okoli izbrane funkcije,</para>
</listitem>
<listitem
><para
>pogled drevesnega pogleda, ki omogoča vizualizacijo odnosov ugnezdenih klicev, skupaj z vključujočo stroškovno metriko za hitro vizualno odkrivanje problematičnih funkcij,</para>
</listitem>
<listitem
><para
>pogled izvorne kode in opomb razzbrinika, ki omogoča ogled podrobnosti o stroških, povezanih z izvornimi vrsticami in navodili za zbirnik.</para>
</listitem>
</itemizedlist>

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

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

<sect1 id="using-profile">
<title
>Ustvarite podatke za vizualizacijo</title>

<para
>Prvič, želimo ustvariti podatke o zmogljivosti z merjenjem vidikov značilnosti časa izvajanja aplikacije z uporabo orodja za profiliranje. &kcachegrind; sama po sebi ne vključuje nobenega orodja za profiliranje, vendar je dobra za uporabo skupaj s &callgrind;, z uporabo pretvornika pa se lahko uporablja tudi za vizualizacijo podatkov, proizvedenih z &oprofile;. Čeprav namen tega priročnika ni dokumentiranje profiliranja s temi orodji, so v naslednjem razdelku kratke vadnice za hiter začetek, s katerimi lahko začnete. </para>

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

<para
>&callgrind; je del <ulink url="http://valgrind.org"
>&valgrind;</ulink
>. Upoštevajte, da se je prej imenoval &calltree;, vendar je bilo to ime zavajajoče. </para>

<para
>Najpogostejša uporaba je predpona ukazne vrstice za zagon aplikacije z <userinput
><command
>valgrind</command
> <option
>--tool=callgrind</option
> </userinput
>, kot v: <blockquote
><para
><userinput
> <command
>valgrind</command
> <option
>--tool=callgrind</option
> <replaceable
>myprogram</replaceable
> <replaceable
>myargs</replaceable
> </userinput
></para
></blockquote
> Ob zaključku programa bo ustvarjena datoteka <filename
>callgrind.out.<replaceable
>pid</replaceable
></filename
>, ki jo lahko naložite v &kcachegrind;. </para>

<para
>Naprednejša uporaba je izpis podatkov profila vsakič, ko se pokliče določena funkcija vaše aplikacije. Npr. za &konqueror;, če si želite ogledati podatke profila samo za upodabljanje spletne strani, se lahko odločite za izpis podatkov vsakič, ko izberete menijski element <menuchoice
><guimenu
>Pogled</guimenu
><guimenuitem
>Znova naloži </guimenuitem
></menuchoice
>. To ustreza klicu <methodname
>KonqMainWindow::slotReload</methodname
>. Uporabite: <blockquote
><para
><userinput
> <command
>valgrind</command
> <option
>--tool=callgrind</option
> <option
>--dump-before=KonqMainWindow::slotReload</option
> <replaceable 
>konqueror</replaceable
> </userinput
></para
></blockquote
> To bo ustvarilo več podatkovnih datotek profila z dodatno zaporedno številko na koncu imena datoteke. Izdelana bo tudi datoteka brez te številke na koncu (konča se le v PID procesa); z nalaganjem te datoteke v &kcachegrind;, se naložijo tudi vse druge in si jih lahko ogledate v <guilabel
>Pregledu delov</guilabel
> in seznamu <guilabel
>Deli</guilabel
>. </para>

</sect2>

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

<para
>&oprofile; je na voljo na <ulink url="http://oprofile.sf.net"
>njegovi domači strani</ulink
>. Sledite navodilom za namestitev na spletnem mestu, vendar preden to storite, preverite, ali ga vaša distribucija že ponuja kot paket (kot &SuSE;). </para>

<para
>Sistemsko profiliranje je dovoljeno le korenskemu uporabniku, saj je mogoče opazovati vsa dejanja v sistemu; zato je treba kot root narediti naslednje. Najprej konfigurirajte postopek profiliranja z &GUI; <command
>oprof_start</command
> ali orodje ukazne vrstice <command
>opcontrol</command
>. Standardna konfiguracija mora biti način časovnika (&TBS;, glejte uvod). Za začetek meritve zaženite <userinput
><command
>opcontrol</command
> <option
>-s</option
></userinput
>. Nato zaženite aplikacijo, ki vas zanima, in nato naredite <userinput
><command
>opcontrol</command
> <option
>-d</option
></userinput
>. S tem boste rezultate meritev zapisali v datoteke v mapo <filename class="directory"
>/var/lib/oprofile/samples/</filename
>. Da bi lahko vizualizirali podatke v &kcachegrind;, naredite v praznem imeniku: <blockquote
><para
><userinput
> <command
>opreport</command
> <option
>-gdf</option
> | <command
>op2callgrind</command
> </userinput
></para
></blockquote
> To bo proizvedlo veliko datotek, eno za vsak program, ki se izvaja v sistemu. Vsakega lahko naložite v &kcachegrind; samega. </para>

</sect2>
</sect1>

<sect1 id="using-basics">
<title
>Osnove uporabniškega vmesnika</title>

<para
>Ko zaženete &kcachegrind; s podatkovno datoteko profila kot argumentom ali po nalaganju z <menuchoice
><guimenu
>Datoteka</guimenu
> <guimenuitem
>Odpri</guimenuitem
></menuchoice
> boste na levi strani videli navigacijsko ploščo s seznamom funkcij ; in na desni glavni del, območje s pogledi za izbrano funkcijo. To območje pogleda je mogoče poljubno konfigurirati za prikaz več pogledov hkrati. </para>

<para
>Ob prvem zagonu bo to območje razdeljeno na zgornji in spodnji del, vsak z različnimi pogledi, ki jih je mogoče izbrati z zavihki. Za premikanje pogledov uporabite kontekstni meni zavihkov in prilagodite razdelilnike med pogledi. Če želite hitro preklapljati med različnimi postavitvami ogleda, uporabite <menuchoice
><shortcut
><keycombo action="simul"
>&Ctrl;<keycap
>→</keycap
> </keycombo
></shortcut
> <guimenu
>Pogled</guimenu
><guisubmenu
>Postavitev</guisubmenu
> <guimenuitem
>Pojdi na Naprej</guimenuitem
></menuchoice
> in <menuchoice
><shortcut
><keycombo action="simul"
>&Ctrl;<keycap
>←</keycap
> </keycombo
> </shortcut
> <guimenu
>Pogled</guimenu
><guisubmenu
>Postavitev</guisubmenu
> <guimenuitem
>Pojdi na prejšnji</guimenuitem
></menuchoice
>. </para>

<para
>Vrsta aktivnega dogodka je pomembna za vizualizacijo: za &callgrind; je to na primer zgrešeno predpomnilnik ali ocena cikla; za &oprofile; je to v najpreprostejšem primeru <quote
>Timer</quote
>. Vrsto dogodka lahko spremenite prek kombiniranega polja v orodni vrstici ali v pogledu <guilabel
>Vrsta dogodka</guilabel
>. Ko izberete funkcijo <function
>main</function
> na levem seznamu, morate dobiti prvi pregled značilnosti časa izvajanja; nato si oglejte pogled grafa klicev. Tam vidite klice, ki se pojavljajo v vašem programu. Upoštevajte, da pogled grafa klicev prikazuje samo funkcije z velikim številom dogodkov. Če dvokliknete funkcijo v grafu, se ta spremeni in prikaže klicane funkcije okoli izbrane. </para>

<para
>Za raziskovanje &GUI; Poleg tega priročnika si oglejte tudi razdelek z dokumentacijo <ulink url="https://kcachegrind.github.io"
>na spletnem mestu</ulink
>. Prav tako vsak gradnik v &kcachegrind; ima <quote
>Kaj je to</quote
> pomoč. </para>
</sect1>

</chapter>


<chapter id="kcachegrind-concepts">
<title
>Osnovni pojmi</title>

<para
>To poglavje pojasnjuje nekatere koncepte &kcachegrind; in uvaja izraze, ki se uporabljajo v vmesniku. </para>

<sect1 id="concepts-model">
<title
>Podatkovni model za podatke o profilu</title>

<sect2>
<title
>Stroškovne entitete</title>

<para
>Štetje stroškov vrst dogodkov (kot so napake L2) se pripišejo stroškovnim entitetam, ki so postavke v povezavi z izvorno kodo ali podatkovnimi strukturami danega programa. Entitete stroškov niso lahko samo preprosta koda ali podatkovni položaji, ampak tudi pozicijska torka. Na primer, klic ima vir in cilj ali pa ima lahko podatkovni naslov vrsto podatkov in položaj kode, kjer je prišlo do njegove dodelitve. </para>

<para
>Entitete stroškov, ki jih pozna &kcachegrind; so podani v nadaljevanju. Preprosti položaji: <variablelist
> <varlistentry
> <term
>Navodilo</term
> <listitem
><para
> Navodilo za zbirnik na določenem naslovu. </para
></listitem
> </varlistentry
> <varlistentry
> <term
>Izvorna vrstica funkcije</term
> <listitem
><para
>Vsa navodila, ki jih prevajalnik (prek informacij o odpravljanju napak) preslika v dano navedeno izvorno vrstico z imenom izvorne datoteke in številko vrstice in ki se izvajajo v kontekstu neke funkcije. Slednje je potrebno, ker se izvorna vrstica znotraj vstavljene funkcije lahko pojavi v kontekstu več funkcij. Navodila brez preslikave v dejansko izvorno vrstico so preslikana v vrstico številka 0 v datoteki <filename
>???</filename
>. </para
></listitem
> </varlistentry
> <varlistentry
> <term
>Funkcija</term
> <listitem
><para
> Vse izvorne vrstice dane funkcije sestavljajo samo funkcijo. Funkcija je podana z imenom in lokacijo v nekem binarnem objektu, če je na voljo. Slednje je potrebno, ker lahko binarni objekti enega programa vsebujejo funkcije z enakim imenom (do teh je mogoče dostopati &eg; s <function
>dlopen</function
> ali <function
>dlsym</function
>; povezovalnik izvajalnega časa razreši funkcije v danem iskalnem vrstnem redu uporabljenih binarnih objektov). Če orodje za profiliranje ne more zaznati imena simbola funkcije, &eg; ker informacije o odpravljanju napak niso na voljo, se običajno uporabi naslov prvega izvedenega ukaza ali <function
>???</function
>. </para
></listitem
> </varlistentry
> <varlistentry
> <term
>Binarni objekt</term
> <listitem
><para
> Vse funkcije, katerih koda je znotraj obsega danega binarnega objekta, bodisi glavnega izvršljivega ali skupna knjižnica. </para
></listitem
> </varlistentry
> <varlistentry
> <term
>Izvorna datoteka</term
> <listitem
><para
> Vse funkcije, katerih prvi ukaz je preslikan v vrstico dane izvorne datoteke. </para
></listitem
> </varlistentry
> <varlistentry
> <term
>Razred</term
> <listitem
><para
>Imena simbolov funkcij so običajno hierarhično urejena v imenskih prostorih, &eg; Imenski prostori C++ ali razredi objektno orientiranih jezikov; tako lahko razred vsebuje funkcije razreda ali samih vdelanih razredov. </para
></listitem
> </varlistentry
> <varlistentry
> <term
>Del profila</term
> <listitem
><para
>Nek časovni odsek izvajanja profila z danim ID-jem niti, ID-jem procesa in ukazno vrstico izvedeno. </para
></listitem
> </varlistentry
> </variablelist
> Kot je razvidno iz seznama, niz stroškovnih entitet pogosto definira drugo stroškovno entiteto; tako obstaja hierarhija vključitve stroškovnih entitet. </para>

<para
>Pozicijske torke: <itemizedlist
> <listitem
><para
> Klic z naslova ukaza na ciljno funkcijo. </para
></listitem
> <listitem
><para
>Klic iz izvorne vrstice v ciljno funkcijo. </para
></listitem
> <listitem
><para
>Klic iz izvorne funkcije v ciljno funkcijo. </para
></listitem
> <listitem
><para
> (Brez)pogojni skok od izvornega do ciljnega ukaza. </para
></listitem
> <listitem
><para
> (Brez)pogojni skok iz izvorne v ciljno vrstico. </para
></listitem
> </itemizedlist
> Skoki med funkcijami niso dovoljeni, ker to nima smisla v grafu klicev; zato je treba konstrukte, kot so obravnavanje izjem in dolgi skoki v C, po potrebi prevesti v izpiranje klicnega sklada. </para>

</sect2>


<sect2>
<title
>Vrste dogodkov</title>

<para
>Poljubne vrste dogodkov lahko določite v podatkih profila tako, da jim daste ime. Njihov strošek, povezan s stroškovno entiteto, je 64-bitno celo število. </para>
<para
>Vrste dogodkov, katerih stroški so določeni v podatkovni datoteki profila, se imenujejo resnični dogodki. Poleg tega lahko podate formule za vrste dogodkov, izračunane iz resničnih dogodkov, ki se imenujejo podedovani dogodki. </para>
</sect2>

</sect1>

<sect1 id="concepts-state">
<title
>Stanje vizualizacije</title>

<para
>Stanje vizualizacije &kcachegrind; okno vključuje: <itemizedlist
> <listitem
><para
> primarni in sekundarni tip dogodka, izbran za prikaz, </para
></listitem
> <listitem
><para
> združevanje funkcij (uporabljeno v <guilabel
>Function Profile</guilabel
> seznam in barvanje entitet), </para
></listitem
> <listitem
><para
> deli profila, katerih stroški bodo vključeni v vizualizacijo, </para
></listitem
> <listitem
><para
> aktivni stroškovna entiteta (&eg; funkcija, izbrana iz stranske plošče profila funkcij), </para
></listitem
> <listitem
><para
> izbrana stroškovna entiteta. </para
></listitem
> </itemizedlist
> To stanje vpliva na poglede. </para>

<para
>Pogledi so vedno prikazani za eno stroškovno entiteto, aktivno. Ko dani pogled ni primeren za stroškovno entiteto, je onemogočen: pri izbiri &eg; &ELF; predmet na seznamu skupine, izvorna opomba nima smisla. </para>

<para
>Na primer, za aktivno funkcijo seznam klicanih prikazuje vse funkcije, ki so bile priklicane iz aktivne funkcije: eno od teh funkcij lahko izberete, ne da bi jo aktivirali. Če je zraven prikazan graf klicev, bo samodejno izbral isto funkcijo. </para>

</sect1>

<sect1 id="concepts-guiparts">
<title
>Deli &GUI;</title>

<sect2>
<title
>Stranski doki</title>
<para
>Stranski doki so stranska okna, ki jih je mogoče postaviti na katero koli obrobo &kcachegrind; okna. Vedno vsebujejo na nek način razvrščen seznam stroškovnih entitet. <itemizedlist>
<listitem
><para
><guilabel
>Profil funkcije</guilabel
> je seznam funkcij, ki prikazuje vključujoče in izključne stroške, število klicev, ime in položaj funkcij. </para
></listitem>
<listitem
><para>
<guilabel
>Pregled delov</guilabel>
</para
></listitem>
<listitem
><para>
<guilabel
>Sklad klicev</guilabel>
</para
></listitem>
</itemizedlist>
</para>
</sect2>

<sect2>
<title
>Razgledno območje</title>
<para
>Območje pogleda, običajno desni del &kcachegrind; glavno okno je sestavljeno iz enega (privzeto) ali več zavihkov, ki so poravnani vodoravno ali navpično. Vsak zavihek ima različne poglede samo ene stroškovne entitete naenkrat. Ime te entitete je navedeno na vrhu zavihka. Če je zavihkov več, je aktiven samo eden. Ime entitete v aktivnem zavihku je prikazano krepko in določa aktivno stroškovno entiteto datoteke &kcachegrind; oknu. </para>
</sect2>

<sect2>
<title
>Območja zavihka</title>
<para
>Vsak zavihek lahko vsebuje do štiri področja pogleda, in sicer zgoraj, desno, levo in dno. Vsako območje lahko vsebuje več zloženih pogledov. Vidni del območja je izbran z vrstico z zavihki. Vrstici z zavihki zgornjega in desnega območja sta na vrhu; vrstici z zavihki levega in spodnjega območja sta na dnu. S kontekstnimi meniji zavihkov lahko določite, kateri pogled naj gre v katero področje. </para>
</sect2>

<sect2>
<title
>Sinhroniziran pogled z izbrano entiteto v zavihku</title>
<para
>Poleg aktivne entitete ima vsak zavihek izbrano entiteto. Ker večina vrst pogledov prikazuje več entitet, pri čemer je aktivna nekako na sredini, lahko izbrani element spremenite tako, da se pomaknete znotraj pogleda (s klikom z miško ali s tipkovnico). Običajno so izbrani elementi prikazani v označenem stanju. Če spremenite izbrano entiteto v enem od pogledov zavihka, vsi drugi pogledi ustrezno označijo novo izbrano entiteto. </para>
</sect2>

<sect2>
<title
>Sinhronizacija med zavihki</title>
<para
>Če je zavihkov več, sprememba izbire na enem zavihku povzroči spremembo aktivacije na naslednjem zavihku, bodisi desno od prejšnjega ali pod njim. Tovrstna povezava naj bi na primer omogočala hitro brskanje po grafih klicev. </para>
</sect2>

<sect2>
<title
>Postavitve</title>
<para
>Postavitev vseh zavihkov v oknu je mogoče shraniti (<menuchoice
><guimenu
>Pogled </guimenu
><guisubmenu
>Postavitev</guisubmenu
></menuchoice
>). Po podvajanju trenutne postavitve (<menuchoice
><shortcut
><keycombo action="simul"
>&Ctrl; <keycap
>+</keycap
></keycombo
></shortcut
> <guimenu
>Pogled</guimenu
> <guisubmenu
>Postavitev </guisubmenu
><guimenuitem
>Dvojnik</guimenuitem
> </menuchoice
>) in spreminjanje nekaterih velikosti ali premikanje pogleda na drugo področje zavihka, lahko hitro preklapljate med staro in novo postavitvijo prek <keycombo action="simul "
> &Ctrl;<keycap
>←</keycap
></keycombo
> in <keycombo action="simul"
>&Ctrl; <keycap
>→</keycap
></keycombo
>. Nabor postavitev bo shranjen med &kcachegrind; seje istega profiliranega ukaza. Trenutni nabor postavitev lahko nastavite kot privzeto za novi &kcachegrind; seje ali obnovite privzeti nabor postavitve. </para>
</sect2>
</sect1>

<sect1 id="concepts-sidedocks">
<title
>Stranski doki</title>

<sect2>
<title
>Ravni profil</title>
<para
><guilabel
>Ravni profil</guilabel
> vsebuje seznam skupin in seznam funkcij. Seznam skupin vsebuje vse skupine, v katerih se porabljajo stroški, odvisno od izbrane vrste skupine. Seznam skupin je skrit, ko je združevanje izklopljeno. </para>
<para
>Seznam funkcij vsebuje funkcije izbrane skupine (ali vse funkcije, če je združevanje izklopljeno), razvrščene po nekem stolpcu, &eg; vključno z lastnimi stroški. Na seznamu je prikazano največje število funkcij, ki jih je mogoče konfigurirati v <menuchoice
><guimenu
>Nastavitve</guimenu
><guimenuitem
>Konfiguriraj KCachegrind</guimenuitem
></menuchoice
>. </para>
</sect2>

<sect2>
<title
>Pregled delov</title>
<para
>Pri izvajanju profila je mogoče ustvariti več podatkovnih datotek profila, ki jih je mogoče skupaj naložiti v &kcachegrind;. Stranski dok<guilabel
>Pregled delov</guilabel
> jih prikazuje, razvrščene vodoravno glede na čas ustvarjanja; velikosti pravokotnika so sorazmerne s stroški, porabljenimi za vsak del. Izberete lahko enega ali več delov, da omejite stroške, prikazane v drugem &kcachegrind; pogled samo na te dele. </para>
<para
>Deli so nadalje razdeljeni na razdelitev in vključujoč način delitve stroškov: <variablelist>
<varlistentry>
<term
><guilabel
>Način particioniranja</guilabel
></term>
<listitem
><para
>Razdelitev je prikazana v skupinah za del podatkov profila glede na izbrano vrsto skupine. Na primer, če &ELF; so izbrane skupine predmetov, vidite barvne pravokotnike za vsak uporabljen &ELF; predmet (knjižnica v skupni rabi ali izvršljiva datoteka), velikosti glede na stroške, porabljene v njem. </para
></listitem>
</varlistentry>
<varlistentry>
<term
><guilabel
>Način diagrama</guilabel
></term>
<listitem
><para
>Prikazan je pravokotnik, ki prikazuje vključujoče stroške trenutne aktivne funkcije v delu. To je spet razdeljeno, da prikaže vključujoče stroške klicanih. </para
></listitem>
</varlistentry>
</variablelist>
</para>
</sect2>

<sect2>
<title
>Sklad klicev</title>
<para
>To je čisto izmišljen <quote
>najverjetnejši</quote
> sklad klicev. Sestavi se tako, da se začne s trenutno aktivno funkcijo in doda klicatelje in klicane z najvišjimi stroški na vrhu in na dnu. </para>
<para
>Stolpca <guilabel
>Strošek</guilabel
> in <guilabel
>Klici</guilabel
> prikazujeta stroške, uporabljene za vse klice funkcije v zgornji vrstici. </para>
</sect2>
</sect1>

<sect1 id="concepts-views">
<title
>Pogledi</title>

<sect2>
<title
>Vrsta dogodka</title>
<para
>Seznam <guilabel
>Vrsta dogodka</guilabel
> prikazuje vse razpoložljive vrste stroškov ter ustrezne lastne in vključujoče stroške trenutne aktivne funkcije za to vrsto dogodka. </para>
<para
>Če na seznamu izberete vrsto dogodka, spremenite vrsto stroškov, prikazanih v celotnem &kcachegrind; izbranemu. </para>
</sect2>

<sect2>
<title
>Seznami klicev</title>
<para
>Ti seznami prikazujejo klice do in iz trenutno aktivne funkcije. Z <guilabel
>Vsi klicatelji</guilabel
> in <guilabel
>Vsi klicatelji</guilabel
> so mišljene tiste funkcije, ki so dosegljive v smeri klicatelja in klicanega, tudi če so druge funkcije vmes. </para>

<para
>Pogledi seznama klicev vključujejo: <itemizedlist>
<listitem
><para
>Neposredne <guilabel
>Klicatelje</guilabel
></para
></listitem>
<listitem
><para
>Neposredne <guilabel
>Klicane</guilabel
></para
></listitem>
<listitem
><para
><guilabel
>Vsi klicatelji</guilabel
></para
></listitem>
<listitem
><para
><guilabel
>Vsi klicani</guilabel
></para
></listitem>
</itemizedlist>
</para>
</sect2>

<sect2>
<title
>Zemljevidi</title>
<para
>Pogled drevesnega zemljevida primarne vrste dogodka, navzgor ali navzdol po hierarhiji klicev. Vsak barvni pravokotnik predstavlja funkcijo; njegova velikost je približno sorazmerna s stroški, porabljenimi za to, medtem ko aktivna funkcija teče (vendar obstajajo omejitve risanja). </para>
<para
>Za <guilabel
>Zemljevid klicateljev</guilabel
> graf prikazuje ugnezdeno hierarhijo vseh klicateljev trenutno aktivirane funkcije; za <guilabel
>Zemljevid klicanih</guilabel
> prikazuje podatke vseh klicanih. </para>
<para
>Možnosti videza najdete v kontekstnem meniju. Če želite dobiti natančna razmerja velikosti, izberite <guimenuitem
>Preskoči nepravilne obrobe</guimenuitem
>. Ker je ta način lahko zelo zamuden, boste morda želeli prej omejiti največjo narisano raven gnezdenja. <guilabel
>Najboljše</guilabel
> določa smer razdelitve za otroke glede na razmerje stranic starša. <guilabel
>Vedno najboljše</guilabel
> odloča o preostalem prostoru za vsakega brata ali sestro. <guilabel
>Prezri razmerja</guilabel
> zavzame prostor za risanje imena funkcije pred risanjem podrejenih elementov. Upoštevajte, da so razmerja velikosti lahko močno napačna. </para>
<para
>Krmarjenje po tipkovnici je na voljo s puščičnimi tipkami levo in desno za premikanje po bratih in sestrah ter s puščičnima tipkama navzgor in navzdol za premikanje po ravni gnezdenja navzgor in navzdol. &Enter; aktivira trenutni element. </para>
</sect2>

<sect2>
<title
>Graf klicev</title>
<para
>Ta pogled prikazuje graf klicev okoli aktivne funkcije. Prikazani stroški so samo stroški, porabljeni med dejanskim izvajanjem aktivne funkcije, &ie; strošek, prikazan za <function
>main()</function
> (če je viden), mora biti enak strošku aktivne funkcije, saj je to del vključujočega stroška <function
>main()</function
> porabljen, medtem ko je delovala aktivna funkcija. </para>
<para
>Pri ciklih modre puščice za klic kažejo, da gre za umeten klic, ki se dejansko nikoli ni zgodil, dodan za pravilno risanje. </para>
<para
>Če je graf večji od območja risanja, je ob strani prikazan pogled iz ptičje perspektive. Obstajajo možnosti pogleda, podobne tistim pri zemljevidih klicev; izbrana funkcija je označena. </para>
</sect2>

<sect2>
<title
>Opombe</title>
<para
>Označeni izvorni ali zbirniški seznami prikazujejo izvorne vrstice ali razstavljena navodila trenutne aktivne funkcije skupaj s (samo)stroški, porabljenimi za izvajanje kode izvorne vrstice ali navodila. Če je prišlo do klica, se v vir vstavijo vrstice s podrobnostmi o klicu: (vključno) stroški, porabljeni v klicu, število klicev in cilj klica. </para>
<para
>Izberite takšno vrstico s podatki o klicu, da aktivirate cilj klica. </para>
</sect2>
</sect1>

</chapter>


<chapter id="commands">
<title
>Referenca ukazov</title>

<sect1 id="kcachegrind-mainwindow">
<title
>Glavno &kcachegrind; okno</title>

<sect2>
<title
>Meni Datoteka</title>
<para>
<variablelist>

<varlistentry>
<term
><menuchoice
><shortcut
> <keycombo
>&Ctrl;<keycap
>N</keycap
></keycombo
> </shortcut
> <guimenu
>Datoteka</guimenu
><guimenuitem
>Novo</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Odpre prazno okno najvišje ravni</action
>, v katerega lahko naložite podatke profila. To dejanje pravzaprav ni potrebno, saj vam <menuchoice
> <guimenu
>Datoteka</guimenu
><guimenuitem
>Odpri</guimenuitem
></menuchoice
> odpre novo okno najvišje ravni, če trenutno že prikazuje nekaj podatkov. </para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><shortcut
> <keycombo
>&Ctrl;<keycap
>O</keycap
></keycombo
> </shortcut
> <guimenu
>Datoteka</guimenu
><guimenuitem
>Odpri</guimenuitem
> </menuchoice
></term>
<listitem>
<para
><action
>Odpre &kde; izbirnik datotek</action
>, da izberete datoteko s podatki profila, ki jo želite naložiti. Če so nekateri podatki že prikazani v trenutnem oknu najvišje ravni, se bo odprlo novo okno; če želite odpreti dodatne podatke o profilu v trenutnem oknu, uporabite <menuchoice
> <guimenu
>Datoteka</guimenu
><guimenuitem
>Dodaj</guimenuitem
></menuchoice
>. </para>
<para
>Ime podatkovnih datotek profila se običajno konča na <literal role="extension"
>.<replaceable
>pid</replaceable
>.<replaceable
>part</replaceable
>-<replaceable
>threadID</replaceable
></literal
>, kjer <replaceable
>del</replaceable
> in <replaceable
>threadID</replaceable
> nista obvezna. <replaceable
>pid</replaceable
> in <replaceable
>part</replaceable
> se uporabljata za več podatkovnih datotek profila, ki pripadajo enemu izvajanju aplikacije. Z nalaganjem datoteke, ki se konča samo z <literal role="extension"
><replaceable
>pid</replaceable
></literal
>, se naložijo tudi vse obstoječe podatkovne datoteke za ta zagon z dodatnimi končnicami. </para>
<informalexample
><para
>Če obstajata podatkovni datoteki profila <filename
>cachegrind.out.123</filename
> in <filename
>cachegrind.out.123.1</filename
>, se bo z nalaganjem prve samodejno naložila tudi druga. </para
></informalexample
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><guimenu
>Datoteka</guimenu
><guimenuitem
>Dodaj</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Doda podatkovno datoteko profila</action
> v trenutno okno. S tem lahko prisilite, da se več podatkovnih datotek naloži v isto okno najvišje ravni, tudi če niso iz istega izvajanja, kot določa konvencija o poimenovanju podatkovnih datotek profila. To lahko na primer uporabite za vzporedno primerjavo. </para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><shortcut
> <keycombo
><keycap
>F5</keycap
></keycombo
> </shortcut
> <guimenu
>Datoteka</guimenu
><guimenuitem
>Znova naloži</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Znova naloži podatke profila</action
>. To je uporabno, če je bila ustvarjena druga podatkovna datoteka profila za že naloženo izvajanje aplikacije. </para
></listitem>
</varlistentry>

<varlistentry>
<term
><menuchoice
><shortcut
> <keycombo
>&Ctrl;<keycap
>Q</keycap
></keycombo
> </shortcut
> <guimenu
>Datoteka</guimenu
><guimenuitem
>Zapusti</guimenuitem
> </menuchoice
></term>
<listitem
><para
><action
>Zapusti</action
> &kcachegrind;</para
></listitem>
</varlistentry>
</variablelist>
</para>

</sect2>

</sect1>
</chapter>

<chapter id="faq">
<title
>Vprašanja in odgovori</title>

<qandaset id="faqlist">


<qandaentry>
<question>
<para
>Zakaj je &kcachegrind;? Nimam pojma. </para>
</question>
<answer>
<para
>&kcachegrind; je v pomoč v pozni fazi razvoja programske opreme, imenovani profiliranje. Če ne razvijate aplikacij, ne potrebujete &kcachegrind;. </para>
</answer>
</qandaentry>

<qandaentry>
<question>
<para
>Kakšna je razlika med <guilabel
>Incl.</guilabel
> in <guilabel
>sam</guilabel
>? </para>
</question>
<answer>
<para
>To so atributi stroškov za funkcije glede neke vrste dogodka. Ker lahko funkcije kličejo druga drugo, je smiselno razlikovati med stroški same funkcije (<quote
>Samo stroški</quote
>) in stroški, vključno z vsemi klicanimi funkcijami (<quote
>Vključni stroški</quote
>). <quote
>Samo</quote
> se včasih imenuje tudi <quote
>Izključni</quote
> stroški. </para>
<para
>Tako boste na primer za <function
>main()</function
> vedno imeli vključujoče stroške skoraj 100 %, medtem ko so lastni stroški zanemarljivi, ko je dejansko delo opravljeno v drugi funkciji. </para>
</answer>
</qandaentry>

<qandaentry>
<question>
<para
>Če dvakrat kliknem na funkcijo spodaj v pogledu <guilabel
>Grafa klicev</guilabel
>, prikaže za funkcijo <function
>main()</function
> enako ceno kot izbrana funkcija. Ali ne bi to moralo biti konstantno pri 100%? </para>
</question>
<answer>
<para
>Aktivirali ste funkcijo pod <function
>main()</function
>, ki očitno stane manj kot sama <function
>main()</function
>. Za vsako funkcijo je prikazan samo del stroškov, porabljen med izvajanjem <emphasis
>aktivirane</emphasis
> funkcije; to pomeni, da cena, prikazana za katero koli funkcijo, nikoli ne more biti višja od cene aktivirane funkcije. </para>
</answer>
</qandaentry>


</qandaset>
</chapter>


<glossary>

<glossentry id="costentity">
<glossterm
>Stroškovni subjekt</glossterm>
<glossdef
><para
>Abstraktna postavka, povezana z izvorno kodo, ki ji je mogoče pripisati dogodek. Dimenzije za stroškovne entitete so lokacija kode (&eg; izvorna vrstica, funkcija), lokacija podatkov (&eg; tip podatkov, do katerega se dostopa, podatkovni objekt), lokacija izvajanja (&eg; nit, proces) in torkeali trojke zgoraj omenjenih pozicij (&eg; klici, dostop do objekta iz izjave, izločeni podatki iz predpomnilnika).</para
></glossdef>
</glossentry>

<glossentry id="eventcosts">
<glossterm
>Stroški dogodka</glossterm>
<glossdef
><para
>Vsota dogodkov neke vrste dogodka, ki se zgodijo, medtem ko je izvedba povezana z neko stroškovno entiteto. Stroški se pripišejo subjektu.</para
></glossdef>
</glossentry>

<glossentry id="eventtype">
<glossterm
>Vrsta dogodka</glossterm>
<glossdef
><para
>Vrsta dogodka, katerega stroške je mogoče pripisati stroškovni entiteti. Obstajajo pravi tipi dogodkov in podedovani tipi dogodkov.</para
></glossdef>
</glossentry>

<glossentry id="inheritedeventtype">
<glossterm
>Podedovani tip dogodka</glossterm>
<glossdef
><para
>Tip navideznega dogodka, viden le v pogledu, definiran s formulo, ki se izračuna iz dejanskih vrst dogodkov.</para
></glossdef>
</glossentry>

<glossentry id="profiledatafile">
<glossterm
>Podatkovna datoteka profila</glossterm>
<glossdef
><para
>Datoteka, ki vsebuje podatke, izmerjene v eksperimentu s profilom, ali njegov del, ali pridobljene z naknadno obdelavo sledi. Njegova velikost je običajno linearna z velikostjo kode programa.</para
></glossdef>
</glossentry>

<glossentry id="profiledatapart">
<glossterm
>Podatkovni del profila</glossterm>
<glossdef
><para
>Podatki iz podatkovne datoteke profila.</para
></glossdef>
</glossentry>

<glossentry id="profileexperiment">
<glossterm
>Preizkus profila</glossterm>
<glossdef
><para
>Zagon programa, ki ga nadzoruje orodje za profiliranje, ki po možnosti ustvari več podatkovnih datotek profila iz delov ali niti zagona.</para
></glossdef>
</glossentry>

<glossentry id="profileproject">
<glossterm
>Profilni projekt</glossterm>
<glossdef
><para
>Konfiguracija za poskuse profilov, ki se uporablja za profiliranje enega programa, morda v več različicah. Primerjave podatkov o profilih so običajno smiselne le med podatki o profilih, proizvedenimi v poskusih enega projekta profila.</para
></glossdef>
</glossentry>

<glossentry id="profiling">
<glossterm
>Profiliranje</glossterm>
<glossdef
><para
>Postopek zbiranja statističnih informacij o značilnostih izvajalnega časa izvajanja programa.</para
></glossdef>
</glossentry>

<glossentry id="realeventtype">
<glossterm
>Vrsta resničnega dogodka</glossterm>
<glossdef
><para
>Vrsta dogodka, ki ga je mogoče izmeriti z orodjem. To zahteva obstoj senzorja za dano vrsto dogodka.</para
></glossdef>
</glossentry>

<glossentry id="trace">
<glossterm
>Sled</glossterm>
<glossdef
><para
>Zaporedje dogodkov s časovnim žigom, ki so se zgodili med sledenjem izvajanju programa. Njegova velikost je običajno linearna glede na čas izvajanja programa.</para
></glossdef>
</glossentry>

<glossentry id="tracepart">
<glossterm
>Del sledi</glossterm>
<glosssee otherterm="profiledatapart"/>
</glossentry>

<glossentry id="tracing">
<glossterm
>Sledenje</glossterm>
<glossdef
><para
>Postopek nadzora izvajanja programa in shranjevanja njegovih dogodkov, razvrščenih po časovnem žigu, v izhodno datoteko, sled.</para
></glossdef>
</glossentry>

</glossary>

<chapter id="credits">

<title
>Zasluge in licenca</title>

<para
>Hvala Julianu Sewardu za njegov odličen &valgrind; in Nicholasu Nethercoteju za &cachegrind; dodatek. Brez teh programov &kcachegrind; ne bi obstajal. Nekaj idej za ta &GUI; so bili tudi od njih. </para>
<para
>Hvala za vsa poročila o napakah in predloge različnih uporabnikov. </para>

<para
>Prevod: Matjaž Jeran<email
>matjaz.jeran@amis.net</email
></para
> &underFDL; </chapter>

&documentation.index;
</book>
