View page as slide show

Profilowanie programów i odpluskwianie pamięci

  • Debbuger pamięci narzędzie do poszukiwania wycieków pamięci i innych błędów związanych z niedozwolonym dostępęm do dynamicznie przydzielanych obszarów pamięci (np. buffer overflow)
    Lista debbugerów pamięci
  • Pomaga zlokalizować funkcje lub fragmenty kodu na które należy zwrócić uwagę przy optymalizacji szybkości działania programu
  • Czy warto optymalizować?
    • Funkcje wołane tysiące razy
    • Funkcje najbardziej kosztowne obliczeniowo
  • Profilowanie pomaga też często wykrywać błędy i lokalizować wady konstrukcji programu (np. niespodziewane wywołania funkcji lub brak wywołań)
  • instrumentacja, wstrzykiwanie do kodu instrukcji monitorujących (np. logi, liczniki wywołań, itp.)
  • profilowanie oparte na zdarzeniach
  • statystyczna, próbkowanie rejestru Program counter
  • symulacja, instruction set simulator (ISS), uruchamianie programu w symulowanym środowisku wirtualnym
  • Dodawane są instrukcje potrzebne do uzyskania informacji o wydajności aplikacji
    • liczniki instrukcji i innych zdarzeń (performance counters)
    • zastępowanie funkcji alokujących pamięć
    • opakowanie wywołań funkcji odpowiednimi mechanizmami zliczającymi
  • Pozwala na:
    • precyzyjne śledzenie wykonywanych instrukcji
    • pomiar czasu wywołań w czasie działania programu
    • debbugowanie i wyłapywanie sytuacji wyjątkowych
    • logging
  • Duży wpływ na wydajność programu profilowanego, plik wykonywalny jest o wiele większy
  • Może to też zaburzać pomiar, tzw Heisenbug
  • Ręczna, dokonywana przez programistę (logi, assercje)
  • Automatyczna modyfikacja kodu (Parasoft, Insure++)
  • Instrumentacja kodu pośredniego, dodawana do assembly lub po dessaemblacji
  • Z wykorzystaniem kompilatorów, symbole debuggera umieszczene w kodzie maszynowym, np. gcc -pg dla gprof, Quantify
  • Binarna, instrumentacja dodawana do kodu maszynowego (ATOM)
  • W czasie działania (runtime): instrumentacja w momencie uruchamiania, program działa pod nadzorem narzędzia profilującego (Valgrind, Pin, DynamicRIO), kod modyfikowany w czasie wykonywania (DynInst)
  • profilowanie oparte na przechwytywanych zdarzeniach, np. tworzenie obiektów, wywołanie metod, odpalenie wątków
  • zakładanie haków (hooks)
  • .NET dołącza agenta profilującego jako serwer COM do CLR (Profiling API).
  • Środowisko uruchomieniowe dostarcza informacji do agenta o wywołaniach metod, utworzeniu obiektów, itd.
  • Agent profilujący potrafi podmienić bytecode profilowanego programu w odpowiedni sposób.
  • Próbkowanie rejestru procesora wskazującego pozycję programu (Program counter) za pomocą przerwań systemu operacyjnego z pewną częstością.
  • Metoda w małym stopniu lub wcale nie ingeruje w kod i wykonanie programu
  • Mniej dokładny pomiar ale pozwala na śledzenie działania programu profilowanego niemal z pełną szybkością.
  • Wyniki są przybliżeniem statystycznym i obarczone są błedem pomiarowym
  • Rozdzielczość pomiaru (ziernistośc danych): zależy od częstości próbkowania. Szybko wykonujące się funkcje bedą niezauważalne
  • profil: ogólne statystyki zaobserwowanych zdarzeń, np. zliczenie wywołań poszczególnych instrukcji, wystarczające dla programów sekwencyjnych (jednowątkowych). Raport zazwyczaj zawiera zestawienie kodu z liczbą wywołań więc jego rozmiar jest liniowy względem liczby linii kodu.
  • ślad (trace), ciąg zaobserwowanych zdarzeń, uwzględnia zależności czasowe także dla programów równoległych. Rozmiar liniowy względem długości ścieżki kodu (instruction path length), z tego względu często niepraktyczny w zastosowaniach.
  • ciągły monitoring na maszynie wirtualnej. Pozwala uruchamiać śledzenie ścieżek w dowolnym momencie, śledzenie na żywo zmian w wydajności, mechanizmy usypiania procesów asynchronicznych w celu dokładniejszego obejrzenia równoległych procesów
  • płaski (flat) - sumaryczne czasy wywołań poszczególnych instrukcji lub funkcji
  • graf wywołań (call graph) - uwzględniają kolejność wywołań i pozwalają oddzielić czas działania funkcji wywołującej od funkcji badanej i funkcji potomnych
  • zależny od wejścia (input sensitive), uzależniają wynik profilowania od rozmiaru i/lub wartości danych wejściowych. Dodają niejako dodatkowy wymiar do profili płaskich i grafów wywołań

  • relacje wywołań pomiędzy funkcjami programu
  • cykle oznaczają rekujencję
  • brak informacji o kontekście

Źródło: wikipedia.org

  • Sampling zbiera dane statystyczne dotyczące wykonywanej aplikacji próbkując obciążenie CPU i stan stosu
  • Instrumentation - pomiary wywołania poszczególnych funkcji
  • Concurrency aplikacje wielowątkowe
  • .NET memory użycie pamięci i garbage collection
  • Tier interaction zawołania ADO.NET do baz danych SQL Serwera

  • Okno Perforamnce Explorer: konfiguracja sesji, uruchamianie testów, porównywanie raportów
  • Performance Session - konfiguracja analizy + raporty
  • Targets - cel analizy: projekt, działający proces, plik wykonywalny
  • Reports - pliki zawierające informacje zebrane podczas analizy
  • Attach/Detach - podłączenie profilowania do działającego procesu
  • Uprawnienia administracyjne - wymagane przez metody próbkowania (sampling) oraz mające dostęp do wywołań systemowych
  • Skompilowanie aplikacji do wersji Release
  • Debug symbols files (.pdb) - m.in. definicja nazw funkcji systemowych
  • Visual Studio Professional/Premium/Ultimate
  • Windows 8, Windows Server 2012, aplikacje Windows Store - wymagają innych technik profilowania, nie wszystkie wymienione tu są wspierane w VS
  • Hot Path najaktywniejsza ścieżka drzewa wywołań funkcji
  • Lista funkcji wykonujących najwięcej pracy
  • Inclusive - łącznie dla całej funkcji, i
  • Exclusive - po odjęciu funkcji wołanych z wnętrza analizowanej funkcji

  • W stałych odstępach czasu pobiera z CPU stan stosu (informacje o autualnie wykonywanych funkcjach)
  • Próbkowanie: domyślnie co 10M cykli (0.01 s dla 1GHz), inne możliwe zdarzenia do próbkowania:
    • błędy stronicowania
    • wywołania systemowe
    • performance counters (CPU counters)
  • w czasie próbkowania zwiekszany jest licznik wywołań (inclusive samples) dla wszystkich funkcji ze stosu
  • Funkcja aktualnie wykonywana otrzymuje zwiększony licznik exclusive sample oraz inclusive sample
  • Inclusive samples - całkowita liczba próbek zebranych dla danej funnkcji
  • Exclusive samples - liczba próbek pobranych w czasie gdy funkcja była wykonywana
  • Pomiar czasu wykonania funkcji, linii kodu i poszczególnych instrukcji
  • Wstrzykiwany kod na początku i końcu badanych funkcji, mierzony jest czas pomiędzy kolejnymi zdarzeniami
  • Sprawdzane jest czy pomiędzy zdarzeniami system dokonywał innych operacji (np. odczyt z dysku, komunikacja miedzy wątkami, …)
  • Dla każdego zarejestrowanego interwału odtwarzany jest stos wywołań w celu określenia funkcji potomnych
  • Elapsed Inclusive - czas wykoanania danej funkcji
  • Elapsed Exclisive - czas z pominięciem czasu funkcji potomnych
  • Application Inlcusive - czas wywołań w czasie których nie nastąpiło wywołanie systemowe
  • Application Exclusive - jak wyżej, z pominięciem czasów funkcji potomnych

  • Okno Error List zawiera ostrzeżenia i wskazówki dotyczące efektywności aplikacji
  • Performance Rules: błędy, ostrzeżenia, informacje


Żródło: http://msdn.microsoft.com

  • VS Profiler pozwala zbierać informacje o zdarzeniach systemu (windows counters, events) i procesora (CPU counters)
  • Windows counters - zdarzenia dostarczane przez infrastrukture diagnostyczną systemu, w zależności od konfiguracji nie muszą wystepować. Dostarczają informacji o wydajności OS, aplikacji, usług i sterowaników
  • CPU counters - zdarzenia związane ze sprzętem zliczane przez CPU
    • Portable Performance counter
    • Platform Events - specyficzne dla danej architektury, nie przenośne
  • Zbiera informacje o rozmiarze i liczbie alokowanych obiektów i obiektów niszczoncyh w garbage collector
  • Zachowuje stan stosu dla każdego takiego zdarzenia
  • Inclusive Sample Count - liczba zdarzeń alokacji obiektu gdy funkcja znajdowała się na stosie
  • Exclusive Sample Count - liczba zdarzeń alokacji obiektu gdy funkcja była wywoływana (była na szczycie stosu)
  • Object Lifetime view - ilość i rozmiar zaalokowanych obiektów oraz informacja o generacji GC w której zostały zniszczone
  • Całkowita zajęcośc pamięci
  • Funkcje, które zaalokowały najwięcej pamięci
  • Lista typów obiektów zajmujących najwięcej miejsca
  • Lista typów posiadających najwięcej instancji

dotMemory dotTrace
  • Pozwala wskazać fragmenty kodu, które należy rozpatrzyć pod względem optymalizacji
  • Dynamiczna analiza: sprawdzane tylko te elementy które zostały wykoane
  • Profilowanie jest kosztowne czasowo i pamięciowo
  • Profilowanie jest obarczone błędami, każda technika ma swoje ograniczenia