Profilozás

A Wikipédiából, a szabad enciklopédiából
Ugrás a navigációhoz Ugrás a kereséshez

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
  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 ideje: 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]