kääntäjän suunnittelu-koodin optimointi

mainokset

optimointi on ohjelmamuunnostekniikka, jossa koodia yritetään parantaa tekemällä siitä vähemmän resursseja (eli suoritinta, muistia) kuluttava ja nopea.

optimoinnissa korkean tason yleiset ohjelmointikonstruktiot Korvataan erittäin tehokkailla matalan tason ohjelmointikoodeilla. Koodin optimointi prosessi on noudatettava kolmea sääntöä alla:

  • tulostuskoodi ei saa millään tavalla muuttaa ohjelman merkitystä.

  • optimoinnin pitäisi lisätä ohjelman nopeutta ja jos mahdollista, ohjelman pitäisi vaatia vähemmän resursseja.

  • optimoinnin pitäisi itsessään olla nopeaa, eikä se saisi viivästyttää kokoamisprosessia.

optimoituun koodiin voidaan pyrkiä prosessin kokoamisen eri tasoilla.

  • alussa käyttäjät voivat muuttaa / järjestää koodin uudelleen tai käyttää parempia algoritmeja koodin kirjoittamiseen.

  • luotuaan välikoodin kääntäjä voi muuttaa välikoodia osoitelaskennoilla ja parantamalla silmukoita.

  • tuottaessaan kohdekonekoodia kääntäjä voi hyödyntää muistihierarkiaa ja SUORITINREKISTEREITÄ.

optimointi voidaan luokitella karkeasti kahteen tyyppiin : koneriippuvaiseen ja koneriippuvaiseen.

Koneriippumaton optimointi

tässä optimoinnissa kääntäjä ottaa välikoodin ja muuntaa koodin osan, johon ei liity mitään suorittimen rekistereitä ja / tai absoluuttisia muistipaikkoja. Esimerkiksi:

do{ item = 10; value = value + item; } while(value

This code involves repeated assignment of the identifier item, which if we put this way:

Item = 10;do{ value = value + item; } while(value

should not only save the CPU cycles, but can be used on any processor.

Machine-dependent Optimization

Machine-dependent optimization is done after the target code has been generated and when the code is transformed according to the target machine architecture. It involves CPU registers and may have absolute memory references rather than relative references. Machine-dependent optimizers put efforts to take maximum advantage of memory hierarchy.

Basic Blocks

Source codes generally have a number of instructions, which are always executed in sequence and are considered as the basic blocks of the code. These basic blocks do not have any jump statements among them, i.e., when the first instruction is executed, all the instructions in the same basic block will be executed in their sequence of appearance without losing the flow control of the program.

A program can have various constructs as basic blocks, like IF-THEN-ELSE, SWITCH-CASE conditional statements and loops such as DO-WHILE, FOR, and REPEAT-UNTIL, etc.

Basic block identification

We may use the following algorithm to find the basic blocks in a program:

  • Etsi otsikkotiedotteita kaikista peruslohkoista, joista peruslohko alkaa:

    • ohjelman ensimmäinen lausunto.
    • lausumat, jotka ovat minkä tahansa haaran kohteena (ehdollinen/ehdoton).
    • väittämät, jotka seuraavat mitä tahansa sivulausetta.
  • Otsikkolauseet ja niitä seuraavat lauseet muodostavat peruslohkon.

  • peruslohko ei sisällä minkään muun peruslohkon otsikkoilmoitusta.

peruslohkot ovat tärkeitä käsitteitä sekä koodintuotannon että optimoinnin näkökulmasta.

Peruslohkoilla

Peruslohkoilla on tärkeä rooli muuttujien tunnistamisessa, sillä niitä käytetään useammin kuin kerran yhdessä peruslohkossa. Jos jotakin muuttujaa käytetään useammin kuin kerran, kyseiselle muuttujalle varattua rekisterimuistia ei tarvitse tyhjentää, ellei lohko suorita suoritusta loppuun.

Ohjausvirtakäyrä

ohjelman peruslohkot voidaan esittää ohjausvirtakuvaajien avulla. Ohjausvirtakuvaaja kuvaa, miten ohjelman ohjaus kulkee lohkojen kesken. Se on hyödyllinen työkalu, joka auttaa optimoinnissa auttamalla löytämään ohjelman ei-toivotut silmukat.

Ohjausvirtauskäyrä

Silmukkaoptimointi

useimmat ohjelmat kulkevat järjestelmässä silmukkana. On tarpeen optimoida silmukoita, jotta voidaan säästää CPU syklejä ja muistia. Silmukoita voidaan optimoida seuraavilla tekniikoilla:

  • invariantti koodi: koodin fragmenttia, joka asuu silmukassa ja laskee saman arvon jokaisessa iteraatiossa, kutsutaan silmukkainvariantiksi koodiksi. Tämä koodi voidaan siirtää pois silmukasta tallentamalla se laskettavaksi vain kerran eikä jokaisen iteraation yhteydessä.

  • Induktioanalyysi: muuttujaa kutsutaan induktiomuuttujaksi, jos sen arvoa muutetaan silmukan sisällä loop-invariant-arvolla.

  • vahvuus vähentäminen: on olemassa lausekkeita, jotka kuluttavat enemmän CPU sykliä, aikaa ja muistia. Nämä ilmaisut tulisi korvata halvemmilla ilmaisuilla ilmaisun tuotosta tinkimättä. Esimerkiksi kertolasku (x * 2) on suorittimen jaksoissa mitattuna kallis kuin (x

Dead-code Elimination

Dead code on yksi tai useampi koodilauseke, jotka ovat:

  • joko koskaan toteutettu tai saavuttamaton,
  • tai jos toteutettu, niiden tuotosta ei koskaan käytetä.

näin kuolleella koodilla ei ole roolia missään Ohjelman toiminnassa ja siksi se voidaan yksinkertaisesti eliminoida.

osittain kuollut koodi

on olemassa joitakin koodilausekkeita, joiden laskettuja arvoja käytetään vain tietyissä olosuhteissa, eli joskus arvoja käytetään ja joskus ei. Tällaisia koodeja kutsutaan osittain kuolleiksi koodeiksi.

osittain kuollut koodi

yllä oleva ohjausvirtakuvaaja kuvaa ohjelmakokonaisuutta, jossa muuttujaa ” a ”käytetään ilmaisun” x * y ” ulostulon osoittamiseen. Oletetaan, että ”a”: lle annettua arvoa ei koskaan käytetä silmukan sisällä.Heti kontrollin poistuttua silmukasta ”a”: lle annetaan muuttujan ” z ” arvo, jota käytettäisiin myöhemmin ohjelmassa. Päätämme tässä, että ”A”: n osoituskoodia ei koskaan käytetä missään, joten se voidaan poistaa.

kuollut koodi

samoin yllä oleva kuva esittää, että ehdollinen lausuma on aina epätosi, mikä tarkoittaa, että tosipohjaisesti kirjoitettua koodia ei koskaan toteuteta, joten se voidaan poistaa.

osittainen redundanssi

redundantit lausekkeet lasketaan useamman kerran rinnakkain ilman, että operandit muuttuvat.kun taas osittais-redundantit lausekkeet lasketaan useammin kuin kerran polulla, ilman että operandit muuttuvat. Esimerkiksi,

tarpeeton lauseke

osittain tarpeeton lauseke

Loop-invariantti koodi on osittain tarpeeton ja se voidaan eliminoida käyttämällä koodiliiketekniikkaa.

toinen esimerkki osittain turhasta koodista voi olla:

If (condition){ a = y OP z;}else{ ...}c = y OP z;

oletamme, että operandien (y ja z) arvot eivät muutu muuttujan A ja muuttujan C osoittamisesta. jos tässä ehtolause on tosi, niin y OP z lasketaan kaksi kertaa, muuten kerran. Koodi motion voidaan poistaa tämän redundanssin, kuten alla:

If (condition){ ... tmp = y OP z; a = tmp; ...}else{ ... tmp = y OP z;}c = tmp;

tässä, onko ehto on tosi tai epätosi; y OP z tulisi laskea vain kerran.

mainokset

Vastaa

Sähköpostiosoitettasi ei julkaista.