Silmukan optimointi - Loop optimization

In kääntäjä teoria , silmukka optimointi on prosessi lisätä suorittamisen nopeutta ja vähentää yleiskustannukset liittyviä silmukoita . Sillä on tärkeä tehtävä välimuistin suorituskyvyn parantamisessa ja rinnakkaiskäsittelyominaisuuksien tehokkaassa hyödyntämisessä . Suurin osa tieteellisen ohjelman suoritusajasta käytetään silmukoihin; sellaisenaan monia kääntäjien optimointitekniikoita on kehitetty niiden nopeuttamiseksi.

Laskennan ja muunnoksen esitys

Koska silmukoiden sisäiset ohjeet voidaan suorittaa toistuvasti, ei usein ole mahdollista antaa rajaa käskyjen suorittamisten lukumäärälle, joihin silmukan optimointi vaikuttaa. Tämä asettaa haasteita perusteltaessa silmukan optimoinnin oikeellisuutta ja hyötyjä, erityisesti optimoitavan laskennan ja suoritettavien optimointien esityksiä.

Optimointi silmukkamuunnosten sekvenssin avulla

Silmukan optimointia voidaan pitää erityisten silmukkamuunnosten sekvenssin (lueteltu jäljempänä tai Compiler-muunnokset korkean suorituskyvyn laskentaa varten ) soveltamisena lähdekoodiin tai välietappiointiin , jokaisella muunnoksella on siihen liittyvä laillisuustesti. Transformaation (tai muunnoksien sekvenssin) on yleensä säilytettävä kaikkien riippuvuuksien ajallinen sekvenssi, jos sillä halutaan säilyttää ohjelman tulos (eli olla laillinen muutos). Transformaation tai muunnosjonon hyödyn arvioiminen voi olla melko vaikeaa tässä lähestymistavassa, koska yhden hyödyllisen muunnoksen soveltaminen voi edellyttää yhden tai useamman muunnoksen aiempaa käyttöä, joka itsessään johtaisi heikentyneeseen suorituskykyyn.

Yleisiä silmukkamuunnoksia ovat:

  • Fissio tai jakauma - silmukkafissio yrittää hajottaa silmukan useiksi silmukoiksi samalla indeksialueella, mutta jokainen uusi silmukka vie vain osan alkuperäisen silmukan rungosta. Tämä voi parantaa referenssin sijaintia , sekä silmukkaan pääsyyn tietoon että silmukan rungossa olevaan koodiin.
  • Fuusio tai yhdistäminen - tämä yhdistää kahden vierekkäisen silmukan rungot, jotka iteroivat saman määrän kertoja (riippumatta siitä, tunnetaanko tämä numero kokoamishetkellä), kunhan ne eivät viittaa toistensa tietoihin.
  • Vaihto tai permutaatio - nämä optimoinnit vaihtavat sisäpiirit ulkoisilla silmukoilla. Kun silmukkamuuttujat indeksoidaan matriisiksi, sellainen muunnos voi parantaa referenssin sijaintia taulukon asettelusta riippuen.
  • Inversio - tämä tekniikka muuttaa standardin samalla kun silmukka tehdään do / while (aka toista / kunnes  ) -silmukkaan, joka kääritään, jos ehdollinen, vähentämällä hyppyjen lukumäärää kahdella tapauksissa, joissa silmukka suoritetaan. Näin kopioidaan kuntotarkistus (suurennetaan koodin kokoa), mutta se on tehokkaampaa, koska hyppyt aiheuttavat yleensä putken putoamisen . Lisäksi, jos alkuperäinen ehto tunnetaan käännöshetkellä ja sen tiedetään olevan sivuvaikutteinen , alkuperäinen if -suojaus voidaan ohittaa.
  • Silmukka-invariantti koodiliike - tämä voi parantaa huomattavasti tehokkuutta siirtämällä laskennan silmukan sisäpuolelta sen ulkopuolelle, laskemalla arvo juuri kerran ennen silmukan alkamista, jos laskelman tuloksena oleva määrä on sama jokaiselle silmukan iteraatiolle ( eli silmukka-invariantti määrä). Tämä on erityisen tärkeää osoitelaskentalausekkeissa, jotka muodostuvat silmukoista taulukkojen yli. Oikean toteutuksen vuoksi tätä tekniikkaa on käytettävä käännöksen kanssa, koska kaikki koodit eivät ole turvallisia siirtää silmukan ulkopuolelle.
  • Rinnakkaistaminen - tämä on erityinen tapaus automaattiseen rinnakkain keskittymiseen, joka keskittyy silmukoihin, muuttamalla niitä toimimaan tehokkaasti usean prosessorin järjestelmissä. Se voidaan tehdä automaattisesti kääntäjillä ( automaattinen rinnakkaisuus ) tai manuaalisesti (lisäämällä rinnakkaisdirektiivejä, kuten OpenMP ).
  • Kääntö - hienovarainen optimointi, joka kääntää järjestyksen, jossa arvot määritetään hakemistomuuttujalle. Tämä voi auttaa poistamaan riippuvuudet ja mahdollistamaan siten muut optimoinnit. Tietyt arkkitehtuurit käyttävät silmukkarakenteita kokoonpanotasolla, jotka laskevat vain yhteen suuntaan (esim. Vähennys-hyppy-jos-ei-nolla [DJNZ]).
  • Aikataulu - tämä jakaa silmukan useisiin osiin, joita voidaan ajaa samanaikaisesti useilla prosessoreilla.
  • Vinoaminen - tätä tekniikkaa sovelletaan sisäkkäiseen silmukkaan, joka iteroi moniulotteisessa matriisissa, jossa jokainen sisäisen silmukan iteraatio riippuu aikaisemmista iteraatioista, ja järjestää ryhmäkäyttönsä uudelleen siten, että ainoat riippuvuudet ovat ulomman silmukan iteraatioiden välillä.
  • Ohjelmiston putkisto - eräänlainen tilauksen ulkopuolinen silmukkatoistojen suorittaminen prosessoritoimintoyksiköiden viiveiden piilottamiseksi.
  • Halkaisu tai kuorinta - tämä yrittää yksinkertaistaa silmukkaa tai eliminoida riippuvuudet katkaisemalla se useiksi silmukoiksi, joilla on samat rungot, mutta iteroivat indeksialueen eri osissa. Erityistapaus on silmukkakuorinta , joka voi yksinkertaistaa silmukkaa ongelmallisella ensimmäisellä iteraatiolla suorittamalla kyseinen iterointi erikseen ennen silmukkaan syöttämistä.
  • Laatoitus tai estäminen - järjestää silmukan iteroidakseen välimuistiin mahtuvien datalohkojen yli.
  • Vektorisointi - yrittää suorittaa niin monta silmukka iteraatiota kuin mahdollista samanaikaisesti SIMD- järjestelmässä.
  • Rullaaminen - kopioi silmukan runko useita kertoja silmukan tilan testaamisten ja hyppyjen lukumäärän vähentämiseksi, mikä voi heikentää suorituskykyä heikentämällä käskyputkea. Silmukan täydellinen rullaus eliminoi kaikki yleiskustannukset (lukuun ottamatta useita käskyhakuja ja lisääntynyttä ohjelman latausaikaa), mutta vaatii, että toistojen lukumäärä on tiedossa käännöshetkellä (paitsi " Just-in-time" -kokoonpanon tapauksessa ). On myös varmistettava, että indeksoitujen muuttujien moninkertainen uudelleenlaskenta ei ole suurempi yleiskustannus kuin osoittimien eteenpäin vieminen alkuperäisessä silmukassa.
  • Kytkentäkytkentä - siirtää ehdollisen silmukan sisäpuolelta sen ulkopuolelle kopioimalla silmukan rungon ja asettamalla versiota siitä ehdollisen jokaisessa lauseessa if ja else .
  • Leikkaus tai nauhojen louhinta - otettiin käyttöön vektoriprosessoreille , silmukkaleikkaus on silmukanmuunnostustekniikka, joka mahdollistaa silmukoiden koodaamisen SIMD (yksi käsky, useita tietoja) -sovelluksiin ja parantaa muistin suorituskykyä. Tämä tarkoittaa sitä, että jokainen vektoritoiminto suoritetaan koolle, joka on pienempi tai yhtä suuri kuin vektorin enimmäispituus tietyssä vektorikoneessa.

Yksimodulaarinen muutoskehys

Yksimodulaarinen muunnoslähestymistapa käyttää yhtä yksimodulaarista matriisia kuvaamaan monien yllä olevien muunnoksien sekvenssin yhdistetty tulos. Keskeistä tässä lähestymistavassa on näkymä kaikista lausekkeen suorituksista n silmukan sisällä kokonaislukupisteiden joukona n- ulotteisessa tilassa, pisteet suoritetaan leksikografisessa järjestyksessä . Esimerkiksi indeksillä i olevan ulkoisen silmukan ja sisäisen silmukan, jossa on indeksi j, sisäkkäisen käskyn suoritukset voidaan yhdistää kokonaislukupareihin . Yksimodulaarisen muunnoksen soveltaminen vastaa tässä tilassa olevien pisteiden kertomista matriisin avulla. Esimerkiksi kahden silmukan vaihto vastaa matriisia .

Yksimodulaarinen muutos on laillinen, jos se säilyttää kaikkien riippuvuuksien ajallisen järjestyksen ; Yksimodulaarisen muutoksen suorituskyvyn vaikutuksen mittaaminen on vaikeampaa. Puutteellisesti sisäkkäiset silmukat ja jotkut muunnokset (kuten laatoitus) eivät sovi helposti tähän kehykseen.

Monikatedraali tai rajoituksiin perustuva kehys

Polyhedraalinen malli käsittelee laajempaa luokan ohjelmia ja muutoksia kuin unimodular puitteissa. Lausuntojen joukon suoritussarjat mahdollisesti epätäydellisesti sisäkkäisissä silmukoissa esitetään joukkona polytopeeja, jotka edustavat lauseiden suorituksia. Affiinimuunnokset sovelletaan näitä polytooppeina, tuottaa kuvaus uuden toteutuksen järjestys. Polytyyppien rajat, datariippuvuudet ja muunnokset kuvataan usein käyttämällä rajoitusjärjestelmiä, ja tätä lähestymistapaa kutsutaan usein rajoitepohjaiseksi lähestymistapana silmukan optimointiin. Esimerkiksi yksi lausunto ulomman silmukan sisällä ' i: = 0 - n ' ja sisäinen silmukka ' j: lle: = 0 - i + 2 ' suoritetaan kerran jokaiselle (i, j) parille siten, että 0 <= i <= n ja 0 <= j <= i + 2 .

Jälleen kerran, muutos on laillinen, jos se säilyttää kaikkien riippuvuuksien ajallisen järjestyksen . Muutoksen hyötyjen arviointi tai tietyn koodin parhaan muunnoksen löytäminen tietyltä tietokoneelta on jatkuvan tutkimuksen kohteena tämän kirjoittamisen ajankohtana (2010).

Katso myös

Viitteet