Kodoptimering

Definition och egenskaper

kodoptimering är någon metod för Kodmodifiering för att förbättra Kodkvaliteten och effektiviteten. Ett program kan optimeras så att det blir en mindre storlek, förbrukar mindre minne, exekverar snabbare eller utför färre ingångs – /utgångsoperationer.

de grundläggande kraven optimeringsmetoder bör uppfylla, är att ett optimerat program måste ha samma utgång och biverkningar som dess icke-optimerad version. Detta krav kan dock ignoreras om nyttan av optimering uppskattas vara viktigare än sannolika konsekvenser av en förändring i programbeteendet.

typer och nivåer av optimering

optimering kan utföras av automatiska optimerare eller programmerare. En optimerare är antingen ett specialiserat mjukvaruverktyg eller en inbyggd enhet i en kompilator (den så kallade optimerings kompilatorn). Moderna processorer kan också optimera exekveringsordningen för kodinstruktioner.

optimeringar klassificeras i optimeringar på hög nivå och låg nivå. Optimeringar på hög nivå utförs vanligtvis av programmeraren, som hanterar abstrakta enheter (funktioner, procedurer, klasser etc.) och tänker på den allmänna ramen för uppgiften att optimera utformningen av ett system. Optimeringar utförda på nivå med elementära strukturella block av källkod-loopar, grenar etc. – brukar kallas högnivåoptimeringar också, medan vissa författare klassificerar dem i en separat (“mitten”) nivå (N. Wirth?). Lågnivåoptimeringar utförs i det skede då källkoden sammanställs i en uppsättning maskininstruktioner, och det är i detta skede som automatiserad optimering vanligtvis används. Assembler programmerare tror dock att ingen maskin, men perfekt, kan göra detta bättre än en skicklig programmerare (men alla är överens om att en dålig programmerare kommer att göra mycket värre än en dator).

vad man ska optimera

med manuell kodoptimering står man inför ett annat problem: man behöver inte bara veta hur exakt optimering ska göras, utan också vilken del av programmet som ska optimeras. På grund av olika orsaker (långsamma inmatningsoperationer, skillnaden i arbetshastigheten hos en mänsklig operatör och en dator osv.) spenderas 90% av körtiden för ett program endast 10% av koden (detta uttalande är ganska spekulativt, med Pareto-principen som en ganska tveksam grund, Men A. Tanenbaum gör det låter övertygande). Eftersom optimering tar ytterligare tid bortsett från den tid du har spenderat på att utveckla programmet, skulle du bättre fokusera på att optimera denna tidskritiska 10% av koden snarare än att försöka optimera hela programmet. Dessa kodfragment är kända som flaskhalsar och kan detekteras av specialverktyg – profiler – som kan mäta den tid som olika delar av programmet tar att utföra.

i praktiken görs dock optimering vanligtvis efter scenen med ” kaotisk “programmering (inklusive sådana metoder som” Copy-Paste”,” we ‘ll see later”,” it ‘s OK this way”) och är därför en blandning av optimering som sådan, refactoring och buggfixar: förenkling av” queer ” – konstruktioner som strlen(path.c_str ()), logiska förhållanden som (a.x != 0 && a.x != 0), och så vidare. Profiler är till liten hjälp med denna typ av optimering. Ändå kan du upptäcka dessa problem med statiska analysverktyg, dvs. verktyg som är utformade för att söka efter semantiska fel, med utgångspunkt i djup analys av källkoden. Som du kan se från ovan nämnda exempel med det konstiga tillståndet kan ineffektiv kod visas som ett resultat av fel (som ett felavtryck i vårt exempel, där a.x != 0 && a.y != 0 borde vara istället). En kraftfull statisk analysator kommer att upptäcka sådana kodfragment och uppmärksamma dem genom att producera varningsmeddelanden.

bra och dåliga resultat av optimering

i programmering bör nästan allt behandlas ur rationalitetssynpunkt – optimering är inget undantag. Det finns en tro på att kod som skrivs av en oerfaren Assembler-programmerare är 3-5 gånger långsammare än kod som genereras av kompilatorn (Zubkov). Allmänt känt är en fras av Knuth angående tidiga optimeringar på låg nivå (som försök att spara på operatörer eller variabler): “för tidig optimering är roten till allt ont”.

de flesta programmerare klagar inte på optimeringar som utförs av optimeraren, varav några är konventionella och obligatoriska. Såsom till exempel svansanropsoptimering på funktionella språk (svansanrop är ett speciellt fall av rekursion, som kan representeras som en slinga).

man bör dock förstå att flera komplexa optimeringar på maskinkodsnivå kan orsaka en stor avmattning av kompileringen. Fördelen de tillåter dig att vinna kan vara alldeles för obetydlig, jämfört med allmänna systemdesign optimeringar (Wirth). Man bör också komma ihåg att moderna språk, med alla sina syntaktiska och semantiska “krusiduller”, har många nyanser och subtiliteter, så att en programmerare som inte är bekant med dem kan bli förvånad över ett resultat av optimering.

ta till exempel C++ och den så kallade Returvärdesoptimeringen, när kompilatorn undviker att kopiera ett tillfälligt objekt som returneras av en funktion. Eftersom kompilatorn utelämnar kopiering kallas denna metod också”Copy elision”. Så följande kod:

#include <iostream> struct C { C() {} C(const C&) { std::cout << "A copy was made.\n"; }}; C f() { return C();} int main() { std::cout << "Hello World!\n"; C obj = f();}

kan ha flera utgångar:

Hello World!A copy was made.A copy was made.Hello World!A copy was made.Hello World!

konstigt som det kan tyckas är alla tre versionerna giltiga eftersom språkstandarden tillåter att man utelämnar samtal från en kopieringskonstruktor i sådana fall, även om konstruktören har biverkningar (12.8 12.8 Kopieringsklassobjekt, punkt 15).

slutsats

därför bör vi alltid överväga att optimera programkoden med hjälp av specialiserade verktyg där det är möjligt, men gör det med stor omsorg och vara redo för sannolikheten för oväntade knep från kompilatorn ibland.

PVS-Studio

en uppsättning diagnostik implementeras i den statiska analysatorn PVS-Studio som gör att du kan hitta vissa situationer där kod kan optimeras. PVS-Studio som alla andra statiska analysatorer kan dock inte fungera som ersättning för profileringsverktygen. Endast dynamiska programanalysatorer kan identifiera flaskhalsarna. Statiska analysatorer vet inte vilka inmatningsdataprogram som får och hur ofta en viss kod körs. Det är därför vi säger att analysatorn föreslår att man implementerar några “mikrooptimeringar” av kod, vilket inte garanterar prestationsvinsterna.

trots den betraktade nackdelen fungerar PVS-Studio analyzer som ett bra komplement till profileringsverktyg. Dessutom, när man arbetar med PVS-Studio varningar, relaterade till optimering, kod blir ofta enklare och kortare. Denna effekt behandlas mer detaljerat i artikeln “Exploring Microoptimizations Using Tizen Code as an Example”.

Lämna ett svar

Din e-postadress kommer inte publiceras.