Profilozás

a dinamikus programelemzés egy formája

A szoftverfejlesztésben a profilozás („program profilozás”, „szoftver profil”) a dinamikus programelemzés egy formája, amely például a program hely- (memória) vagy időbeli összetettségét, az egyes utasítások felhasználását vagy a funkcióhívások gyakoriságát és időtartamát méri. A profilozási információkat a program optimalizálásában használják fel.

A profilozást úgy érhetjük el, hogy a program forráskódját vagy annak bináris futtatható formáját instrumentáljuk egy „profilozó”-nak (vagy kódprofilozónak) nevezett eszközzel. A profilozók számos különféle technikát használhatnak, például eseményalapú, statisztikai, műszeres és szimulációs módszereket.

Programesemények összegyűjtése szerkesztés

A profilkészítők sokféle technikát használnak az adatok gyűjtésére, ideértve a hardvermegszakításokat, a kódmérést, az utasításkészlet-szimulációt, az operációs rendszer kampóit és a teljesítményszámlálókat. A profilokat használják a teljesítménymérnöki folyamatban.

Profilerek használata szerkesztés

 
CodeAnalyst profiler grafikus kimenete

„ A program-elemző eszközök rendkívül fontosak a program viselkedésének megértéséhez. A számítógépes tervezőknek ilyen eszközökre van szükségük annak értékeléséhez, hogy a programok mennyire teljesítenek új architektúrákban. A szoftveríróknak eszközökre van szükségük a programok elemzéséhez és a kritikus kódrészek azonosításához. A fordítóírók gyakran használnak ilyen eszközöket annak kiderítésére, hogy az utasítások ütemezése vagy az ágbecslési algoritmus mennyire teljesít jól ...”

– ATOM, PLDI

A profilozó kimenete lehet:

  • A megfigyelt események statisztikai összefoglalása (profil)

Az összefoglaló profilinformációkat gyakran jelöléssel látják el a forráskód-kijelentésekkel szemben, ahol az események bekövetkeznek, tehát a mérési adatok mérete arányos a program kódméretével.

/* ------------ source------------------------- count */             
0001             IF X = "A"                     0055
0002                THEN DO                       
0003                  ADD 1 to XCOUNT           0032
0004                ELSE
0005             IF X = "B"                     0055
  • A rögzített események stream-je (trace)
A szekvenciális programokhoz általában elegendő az összefoglaló profil, de a párhuzamos programok (üzenetvárakozás vagy szinkronizálási problémák) teljesítményproblémái gyakran az események időbeli viszonyától függenek, így teljes nyomkövetésre van szükség a történtek megértéshez.
A (teljes) nyomkövetés mérete lineárisan arányos a program utasítási útvonalának hosszával, ami kissé célszerűtlenné teszi. Ezért a nyomkövetés a program egyik pontján inicializálható, és egy másik ponton befejezhető a kimenet korlátozása érdekében.
  • Folyamatos interakció a hypervisor-ral (folyamatos vagy időszakos monitorozás például a képernyőn keresztül)
Ez lehetőséget ad arra, hogy a nyomkövetést a végrehajtás során bármely kívánt ponton be- vagy kikapcsolhassa, a folyamatban lévő metrikák megtekintése mellett a (még mindig végrehajtó) programról. Ezenkívül lehetőséget ad arra, hogy az aszinkron folyamatokat felfüggesszük a kritikus pontokon, hogy részletesebben megvizsgáljuk az egyéb párhuzamos folyamatokkal való interakciókat.

A profilozó alkalmazható egyedi módszerre vagy egy modul vagy program terjedelmében, a teljesítmény szűk keresztmetszeteinek azonosításához a hosszan futó kód nyilvánvalóvá tétele révén. A profilozó felhasználható a kód időzítés szempontjából történő megértésére, azzal a céllal, hogy optimalizálja azt a különböző futási feltételek vagy különböző terhelések kezelésére. A profilozási eredmények felhasználhatók az egyes algoritmusok tervezésének és optimalizálásának irányításához. A profilozók be vannak építve néhány alkalmazás teljesítménykezelő rendszerébe, amelyek összesítik a profilozási adatokat, hogy betekintést nyújtsanak a tranzakciós munkaterhelésébe az elosztott alkalmazásokban.

Történelem szerkesztés

A teljesítmény-elemző eszközök az 1970-es évek elejétől léteztek az IBM / 360 és az IBM / 370 platformokon, általában olyan időzítő megszakításokon alapultak, amelyek meghatározott időközönként rögzítették a program állapotszót (PSW) a "forró pontok" észlelésére a futtatott kódban. Ez a mintavétel korai példája (lásd alább). 1974 elején az utasításkészlet-szimulátorok teljes nyomkövetést és egyéb teljesítmény-figyelő funkciókat tettek lehetővé.

A profilozás-vezérelt program elemzése a Unixon 1973-ba nyúlik vissza, amikor a Unix rendszerek tartalmaztak egy alapvető eszközt, a prof-ot, amely felsorolta az egyes függvényeket, és hogy azok a program futási idejének mekkora részét vették igénybe. 1982-ben a gprof kiterjesztette a koncepciót egy teljes hívás gráf elemzésre.[1]

1994-ben Amitabh Srivastava és Alan Eustace a Digital Equipment Corporation-ből publikáltak egy tanulmányt, amelyben leírják az ATOM-ot (Analysis Tools with OM). Az ATOM platform egy programot a saját profilozójává konvertál: fordításkor illeszt be kódot az analizálandó programba. Ez a beillesztett kód elemzési adatokat szolgáltat. Ez a technika - egy program módosítása önmagának elemzésére - „instrumentation” néven ismert.

2004-ben mind a gprof, mind az ATOM tanulmányok megjelentek az 50 legbefolyásosabb PLDI tanulmányok listáján az 1999-ben záruló 20 éves időszakra.[2]

Profiltípusok a kimenet alapján szerkesztés

Lapos profilozó (Flat profiler) szerkesztés

Hívási-gráf profilozó (Call-graph profiler) szerkesztés

A lapos profilozók kiszámítják az átlagos hívási időket a hívások alapján, és nem bontják fel a hívási időket a hívó fél vagy a környezet alapján.

Bemenet érzékeny profilozó szerkesztés

Bemenet érzékeny profilozók hozzáadnak egy további dimenziót a lapos vagy hívás-gráfos profilozókhoz, a teljesítménymutatóknak a bemeneti munkaterhelések jellemzőivel való összekapcsolásával, például a bemenet méretével vagy a bemeneti értékekkel. Diagramokat generálnak, amelyek jellemzik, hogy az alkalmazás teljesítménye hogyan alakul a bemenet függvényében.

Az adatok részletessége profilozó típusokban szerkesztés

A profilerek, amelyek maguk is programok, elemzik a célprogramokat, és információkat gyűjtenek azok végrehajtásáról. Az adatok részletessége, az, hogy a profilozók hogyan gyűjtik az információkat, esemény-alapú vagy statisztikai profilokba sorolják őket. A profilkészítők megszakítják a program végrehajtását az információk gyűjtése érdekében, ami korlátozott felbontást eredményezhet az időmérésekben. Az alapvető blokk profilerek számos gépi óraszám-ciklust jelentenek, amelyek az egyes kódsorok végrehajtására vonatkoznak, vagy ezek összeadásán alapuló időzítést; az alapvető blokkonként jelentett időzítések nem tükrözik a gyorsítótár találatai és hiányosságai közötti különbséget. [3] [4]

Esemény alapú profilozók szerkesztés

Az itt felsorolt programozási nyelvek eseményalapú profilozókkal rendelkeznek:

  • Java: a JVMTI (JVM Tools Interface) API, korábban JVMPI (JVM Profiling Interface), horgokat biztosít a profilerek számára olyan események csapdájához, mint a hívások, a class-load, unload, thread enter leave.
  • .NET: Profilozó ügynököt COM szerverként csatolhat a CLR-hez a Profiling API használatával. A Javához hasonlóan a runtime különféle visszahívásokat biztosít az ügynökbe olyan események csapdájához, mint a JIT / belépés / távozás, az objektum létrehozása stb., Különös tekintettel arra, hogy a profilozó ügynök tetszőleges módon átírhatja a cél alkalmazás bájtkódját.
  • Python: A Python profilozása magában foglalja a profilmodult, a hotshotot (amely hívás-gráf alapú), és a 'sys.setprofile' függvényt használja az olyan események csapdájához, mint a c_{call,return,exception}, python _{call,return,exception}.
  • Ruby: A Ruby is a Pythonhoz hasonló felületet használ a profilkészítéshez. Lapos profilozóval a profil.rb-ben, a modulban és a ruby-prof-ban egy C-kiterjesztés van jelen.

Statisztikai profilozók szerkesztés

Néhány profilkészítő mintavétel útján működik. A mintavételi profilerek rendszeres időközönként tesztelik a célprogram hívásvermét az operációs rendszer megszakításokkal. A mintavételi profilok általában kevésbé pontosak és specifikusak numerikusan, de lehetővé teszik a célprogramnak a teljes sebesség közeli futtatását.

A kapott adat nem pontos, hanem statisztikai közelítés. „A tényleges hibamennyiség általában egynél több mintavételi periódust tartalmaz. Valójában, ha egy érték a mintavételi periódus n-szerese, akkor az abban várható hiba n mintavételi időszak négyzetgyöke.” [5]

A gyakorlatban a mintavételes profilerek gyakran pontosabb képet nyújtanak a célprogram végrehajtásáról, mint más megközelítések, mivel kevésbé támadják a célprogramot, és így nem járnak annyi mellékhatással (például a memória gyorsítótárain). Mivel ezek nem annyira érintik a végrehajtási sebességet, felismerhetnek olyan problémákat, amelyek egyébként rejtve maradnak. Relatív immunitásuk van a kicsi, gyakran hívott rutinok vagy „szűk” ciklusok költségeinek túlbecslésére is. Megmutathatják a felhasználói módban eltöltött idő és a megszakítható kernelmód közötti relatív időt.

Ennek ellenére a megszakítások kezelésére szolgáló kernelkód kisebb veszteségeket okoz a CPU ciklusokban, elterelte a gyorsítótár használatát, és nem képes megkülönböztetni a megszakíthatatlan kernelkódban fellépő különböző feladatokat (mikroszekundum-tartományú tevékenység).

A dedikált hardverek meghaladhatják ezt: az ARM Cortex-M3 és néhány újabb MIPS processzor JTAG interfésze rendelkezik egy PCSAMPLE regiszterrel, amely valóban észlelhetetlen módon veszi a programszámláló mintáját, lehetővé téve a lapos profil (flat profile) nem tolakodó begyűjtését.

Néhány általánosan használt statisztikai profilkészítő Java / kezelt kódhoz a SmartBear Software AQtime és a Microsoft CLR Profiler. Ezek a profilozók támogatják a natív kód profilozását, többek között az Apple Inc. Shark (OSX), OProfile (Linux), Intel VTune és Parallel Amplifier (az Intel Parallel Studio része) és az Oracle Performance Analyzer segítségével.

Instrumentáció szerkesztés

Ez a technika hatékonyan hozzáadja az utasításokat a célprogramhoz a szükséges információk összegyűjtésére. Egy program instrumentálása teljesítményváltozásokat okozhat, és bizonyos esetekben pontatlan eredményekhez és / vagy heisenbug-okhoz vezethet. A hatás attól függ, hogy milyen információkat gyűjtenek, az időzített adatok részletezett szintjéről, és attól, hogy az alapvető blokk profilozást használják-e az instrumentálással együtt. Például, ha kódot ad hozzá minden eljárás / rutin hívás megszámolásához, akkor valószínűleg kisebb hatással lesz, mint az, ha megszámolja az egyes állítások teljesülését. Néhány számítógép rendelkezik speciális hardverrel az információk gyűjtésére; ebben az esetben a programra gyakorolt hatás minimális.

Az instrumentálás kulcsszerepet játszik a profilerek rendelkezésére álló ellenőrzési szint és az időfelbontás mennyiségének meghatározásában.

  • Manuális: a programozó hajtja végre, pl. utasítások hozzáadásával a futási idő kifejezett kiszámításához, egyszerűen számoljon eseményeket vagy hívásokat mérési API-khoz, mint például az Application Response Measurement szabvány.
  • Automatikus forrásszint: a instrumentálás hozzáadása a forráskódhoz egy automatikus eszközzel, egy beállított szabály szerint.
  • Középnyelv: az assembly vagy a lefordított bytekódokhoz hozzáadott instrumentálás, amely támogat több magasabb szintű forrásnyelvet, és elkerüli a (nem szimbolikus) bináris offset újraírási problémákat.
  • Fordítóprogrammal támogatott
  • Bináris fordítás: az eszköz hozzáadja az instrumentálást egy összeállított végrehajtható fájlhoz.
  • Futásidejű instrumentálás: közvetlenül a végrehajtás előtt a kód instrumentélva. A program futását az eszköz teljes mértékben felügyeli és irányítja.
  • Futás közbeni beszúrás: könnyebb, mint a futásidejű instrumentálás. A kódot futási időben módosítják úgy, hogy ugrásaik legyenek a segítő funkciókhoz.

Interpreter instrumentálás szerkesztés

  • Az interpreter hibakeresési opciók lehetővé teszik a teljesítménymutatók összegyűjtését, mivel az interpreter találkozik minden cél feltétellel. A bájtkód, a vezérlőtábla vagy a JIT interpreterek három példa, amelyek általában teljes mértékben ellenőrzik a célkód végrehajtását, ezáltal lehetővé téve a rendkívül átfogó adatgyűjtési lehetőségeket.

Hypervisor/szimulátor szerkesztés

  • Hypervisor: Az adatokat az (általában) nem módosított program hypervisor alatt történő futtatásával gyűjtik. Példa: SIMMON
  • Szimulátor és Hypervisor: interaktív módon és szelektíven gyűjtött adatok a nem módosított program futtatásával egy utasításkészlet-szimulátor alatt.

Lásd még szerkesztés

Hivatkozások szerkesztés

  1. S.L. Graham, P.B. Kessler, and M.K. McKusick, gprof: a Call Graph Execution Profiler, Proceedings of the SIGPLAN '82 Symposium on Compiler Construction, SIGPLAN Notices, Vol. 17, No 6, pp. 120-126; doi:10.1145/800230.806987
  2. 20 Years of PLDI (1979–1999): A Selection, Kathryn S. McKinley, Editor
  3. Timing and Profiling - Basic Block Profilers. OpenStax CNX Archive. [2020. június 28-i dátummal az eredetiből archiválva]. (Hozzáférés: 2020. június 26.)
  4. (1994) „Optimally profiling and tracing programs”. ACM Transactions on Programming Languages and Systems 16 (4), 1319–1360. o, Kiadó: ACM Digital Library. [2018. május 18-i dátummal az eredetiből archiválva]. DOI:10.1145/183432.183527. (Hozzáférés: 2020. június 26.)  
  5. Statistical Inaccuracy of gprof Output Archiválva 2012. május 29-i dátummal a Wayback Machine-ben.

További információk szerkesztés