This shows you the differences between two versions of the page.
sde:laboratoare:10 [2019/04/15 19:00] iuliana.marin |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Laboratorul 10 - Profiling & Debugging ===== | ||
- | ===== Materiale ajutătoare ===== | ||
- | |||
- | *[[http://elf.cs.pub.ro/so/res/laboratoare/lab07-slides.pdf | lab010-slides.pdf]] | ||
- | ===== Latency Comparison Numbers ===== | ||
- | ^ Operation ^ Time (ns) ^ Notes ^ | ||
- | | ''L1 cache reference '' | 0.5 ns | | | ||
- | | ''Branch mispredict '' | 5 ns | | | ||
- | | ''L2 cache reference '' | 7 ns | 14x L1 cache | | ||
- | | ''Mutex lock/unlock '' | 25 ns | | | ||
- | | ''Main memory reference '' | 100 ns | 20x L2 cache, 200x L1 cache | | ||
- | | ''Compress 1K bytes with Zippy'' | 3,000 ns | | | ||
- | | ''Send 1K bytes over 1 Gbps network'' | 10,000 ns | 0.01 ms | | ||
- | | ''Read 4K randomly from SSD* '' | 150,000 ns | 0.15 ms | | ||
- | | ''Read 1 MB sequentially from memory'' | 250,000 ns | 0.25 ms | | ||
- | | ''Round trip within same datacenter '' | 500,000 ns | 0.5 ms | | ||
- | | ''Read 1 MB sequentially from SSD* '' | 1,000,000 ns | 1 ms, 4x memory| | ||
- | | ''Disk seek '' | 10,000,000 ns | 10 ms, 20x datacenter roundtrip| | ||
- | | ''Read 1 MB sequentially from disk '' | 20,000,000 ns | 20 ms, 80x memory, 20x SSD| | ||
- | | ''Send packet Caracal - NY - Caracal '' | 150,000,000 ns | 150 ms | | ||
- | |||
- | ===== Link-uri către secțiuni utile ===== | ||
- | |||
- | ==== Linux ==== | ||
- | * [[#profiler_si_tehnici de profiling|Profiler și tehnici de profiling]] | ||
- | * [[#unelte_de_profiling|Unelte de profiling]] | ||
- | * [[#utilizare_perf|Utilizare perf]] | ||
- | * [[#unelte_de_debugging|Unelte de debugging]] | ||
- | |||
- | |||
- | ===== Profiler și tehnici de profiling ===== | ||
- | Un **profiler** este un utilitar de analiză a **performanței** care ajută programatorul să determine punctele critice – **bottleneck** – ale unui program. Acest lucru se realizează prin investigarea comportamentului programului, evaluarea consumului de memorie și relația dintre modulele acestuia. | ||
- | |||
- | Suportul pentru profilere este disponibil la nivel de: | ||
- | |||
- | ***bibliotecă C** (GNU libc), prin informații legate de timpul de viață al alocărilor de memorie, | ||
- | ***compilator**, prin modificarea codului în tehnica de **instrumentare** se poate realiza ușor în procesul de compilare, compilatorul fiind cel ce inserează secțiunile de cod necesare, | ||
- | ***nucleu** al sistemului de operare, prin punerea la dispoziție de apeluri de sistem specifice, | ||
- | ***hardware**, unele procesoare sunt dotate cu contoare de temporizare ([[http://en.wikipedia.org/wiki/Time_Stamp_Counter | Time Stamp Counter - TSC]]) sau contoare de performanță care numără evenimente precum cicluri de procesor sau TLB miss-uri. | ||
- | |||
- | Două moduri prin care se realizează profiling-ul sunt prezentate în continuare: | ||
- | |||
- | ==== Tehnica de instrumentare (instrumentation)==== | ||
- | Profiler-ele bazate pe această tehnică necesită de obicei **modificări** în codul programului: se inserează secțiuni de cod la începutul și sfârșitul funcției ce se dorește analizată. De asemenea, se rețin și funcțiile apelate. Astfel, se poate estima timpul total al apelului în sine cât și al apelurilor de subfuncții. Dezavantajul major al acestor profilere este legat de modificarea codului: în funcții de dimensiune scăzută și des apelate, acest overhead poate duce la o interpretare greșită a rezultatelor. | ||
- | ====Tehnica de eșantionare (sampling)==== | ||
- | Profiler-ele bazate pe sampling **nu fac schimbări** în codul programului, ci verifică periodic procesorul cu scopul de a determina ce funcție (instrucțiune) se execută la momentul respectiv. Apoi estimează frecvența și timpul de execuție al unei anumite funcții într-o perioadă de timp. | ||
- | ====Unelte de profiling==== | ||
- | În continuare sunt prezentate câteva unelte folosite în profiling. | ||
- | ====perfcounters==== | ||
- | Majoritatea procesoarelor moderne oferă registre speciale (''performance counters'') care contorizează diferite tipuri de evenimente hardware: instrucțiuni executate, cache-miss-uri, instrucțiuni de salt anticipate greșit, fără să afecteze performanța nucleului sau a aplicațiilor. Aceste registre pot declanșa întreruperi atunci când se acumulează un anumit număr de evenimente și astfel se pot folosi pentru analiza codului care rulează pe procesorul în cauză. | ||
- | |||
- | Subsistemul ''perfcounters'': | ||
- | * se găsește în nucleul Linux începând cu versiunea [[http://lwn.net/Articles/339361/|2.6.31]] (''CONFIG_PERF_COUNTERS=y'') | ||
- | * este înlocuitorul lui ''oprofile'' | ||
- | *oferă suport pentru: | ||
- | * ''evenimente hardware'' (instrucțiuni, accese cache, ciclii de magistrală). | ||
- | *''evenimente software'' (page fault, cpu-clock, cpu migrations). | ||
- | * ''tracepoints'' (e.g: sys_enter_open, sys_exit_open). | ||
- | |||
- | ====perf==== | ||
- | Utilitarul ''perf'' este interfața subsistemului ''perfcounters'' cu utilizatorul. Oferă o linie de comandă asemănătoare cu ''git'' și nu necesită existența unui daemon. | ||
- | |||
- | Un tutorial despre perf găsiți [[https://perf.wiki.kernel.org/index.php/Tutorial|aici]]. | ||
- | ====Utilizare perf==== | ||
- | <code bash> | ||
- | $ perf [--version] [--help] COMMAND [ARGS] | ||
- | </code> | ||
- | |||
- | Cele mai folosite ''comenzi'' sunt: | ||
- | *''annotate'' - Citește ''perf.data'' și afișează codul cu adnotări | ||
- | *''list'' - Listează numele simbolice ale tuturor tipurilor de evenimente ce pot fi urmărite de ''perf'' | ||
- | *''lock'' - Analizează evenimentele de tip lock | ||
- | *''record'' - Rulează o comandă și salvează informațiile de profiling în fișierul perf.data | ||
- | *''report'' - Citește perf.data (creat de perf record) și afișează profilul | ||
- | *''sched'' - Utilitar pentru măsurarea proprietăților planificatorului (latențe) | ||
- | *''stat'' - Rulează o comandă și afișează statisticile înregistrate de subsistemul performance counters | ||
- | *''top'' - Generează și afișează informații în timp real despre încărcarea unui sistem | ||
- | ====perf list==== | ||
- | [[http://manpages.ubuntu.com/manpages/natty/man1/perf-list.1.html | man perf-list]] | ||
- | |||
- | Afișează numele simbolice ale tuturor tipurilor de evenimente ce pot fi urmărite de ''perf''. | ||
- | <code bash> | ||
- | $ perf list | ||
- | List of pre-defined events (to be used in -e): | ||
- | |||
- | cpu-cycles OR cycles [Hardware event] | ||
- | instructions [Hardware event] | ||
- | |||
- | cpu-clock [Software event] | ||
- | page-faults OR faults [Software event] | ||
- | |||
- | L1-dcache-loads [Hardware cache event] | ||
- | L1-dcache-load-misses [Hardware cache event] | ||
- | |||
- | rNNN [Raw hardware event descriptor] | ||
- | |||
- | mem:<addr>[:access] [Hardware breakpoint] | ||
- | |||
- | syscalls:sys_enter_accept [Tracepoint event] | ||
- | syscalls:sys_exit_accept | ||
- | </code> | ||
- | Atunci când un eveniment nu este disponibil în forma simbolică, poate fi folosit cu perf în forma procesorului din sistemul analizat. | ||
- | |||
- | |||
- | |||
- | |||
- | |||