Þýðandi
Compiler (einnig þýðandi; úr ensku compile, gather 'eða latin compilare, heap') er tölvuforrit , hægt er að framkvæma kóða tiltekins forritunarmáls sem er þýtt í form tölvu (beint). Þetta býr til meira eða minna beint keyranlegt forrit. Þetta er aðgreina frá túlkum , td fyrir snemma útgáfur af BASIC , sem búa ekki til vélakóða .
Stundum er gerður greinarmunur á hugtökunum þýðandi og þýðandi. Þýðandi þýðir forrit úr formlegu uppsprettumáli í merkingarfræðilega jafngildi á formlegu markmáli. Þýðendur eru sérstakar þýðendur sem snerist forrit númer frá vandamálinu stilla forritunarmál , svokallaða hátt - Level Tungumál inn executable kóða vél á tilteknu arkitektúr eða millistig kóða ( bætakóða , p-kóða eða NET kóða ). Þessi aðgreining milli hugtaka þýðanda og þýðanda er ekki gerð í öllum tilvikum.
Ferlið þýðingar er einnig þekkt sem taka saman eða breytingar (eða með samsvarandi sögn ). Hið gagnstæða, þ.e. öfug þýðing á vélmáli í frumtexta tiltekins forritunarmáls, er kölluð niðurfelling og samsvarandi forrit eru kölluð afritarar .
hugtök
Þýðandi er forrit sem tekur sem inntak forrit sem er mótað á upprunamáli og þýðir það í merkingarfræðilega jafngilt forrit á markmáli. [1] Sérstaklega er þess krafist að forritið sem býr til skili sömu niðurstöðum og gefið forrit. Frummálinu Assembler er oft talin undantekning - þýðandi hennar (í vél númer) er kallað "Assembler" og er i. A. ekki nefndur „þýðandi“. Starf þýðandans felur í sér mikið úrval undirverkefna, allt frá setningafræðigreiningu til miðamyndagerðar. Annað mikilvægt verkefni er að bera kennsl á og tilkynna villur í frumforritinu.
Orðið „þýðandi“ kemur frá ensku „to compile“ og þýðir „þýðandi“ í raunverulegum skilningi orðsins. Á fimmta áratugnum var hugtakið ekki enn fast fest í tölvuheiminum. [2] Upphaflega vísaði þýðandinn til hjálparforrits sem sameinaði heildarforrit úr einstökum undirferlum eða formúlumati til að sinna sérstökum verkefnum. (Þetta verkefni er nú framkvæmt af tenglinum , sem þó er einnig hægt að samþætta í þýðandann.) Einstöku undirleiðirnar voru enn skrifaðar „með hendi“ á vélmáli . Frá 1954 kom hugtakið „algebrufræðingur“ fyrir forrit sem breytti formúlum sjálfkrafa í vélakóða. „Algebraíska“ féll frá með tímanum. [3]
Í lok fimmta áratugarins var hugtakið þýðandi enn umdeilt í enskumælandi löndum. Þróunarteymi Fortran hélt á hugtakinu „þýðandi“ í mörg ár til að vísa til þýðandans. Þessi tilnefning er meira að segja innifalin í nafni Fortran forritunarmálsins sjálfs: Fortran er samsett úr For mula og Tran slation, það er í grófum dráttum formúluþýðingu. Það var ekki fyrr en 1964 að hugtakið þýðandi hafði yfir hugtakið þýðandi í tengslum við Fortran. Að sögn Carsten Busch er „sérstök kaldhæðni í sögunni“ að hugtakið þýðandi sé þýtt sem „þýðandi“ á þýsku. [2] [4] Hins vegar nota sum þýsk rit einnig enska hugtakið þýðandi í stað þýðanda. [5]
Í þrengri merkingu nota sum þýskt rit þó aðeins tæknilega hugtakið þýðandi ef upprunamálið er hærra forritunarmál en markmálið. [6] Dæmigerð forrit eru þýðing á háu stigi forritunarmáls yfir í vélatölvu tölvu, auk þýðingar í bytecode sýndarvél . Markmál þýðenda (í þessum skilningi) getur einnig verið samsett tungumál . Þýðandi til að þýða samsetningaruppsprettuforrit á vélmál er kallað samsetjari . [7]
saga
Konrad Zuse var þegar að skipuleggja þýðanda fyrir fyrsta æðra forritunarmálið sem hannað var, Plankalkül eftir Konrad Zuse - samkvæmt hugtökum í dag. Zuse kallað eitt forrit reikniaðgerðir áætlun og eins snemma og 1944 fékk hugmyndina að svokölluð áætlun framleiðslu tæki, sem ætti sjálfkrafa að búa til sleginn borði með samsvarandi vél áætlun um Zuse Z4 tölva frá stærðfræðilega mótuð útreikning áætlun. [8.]
Meira áþreifanlegt en hugmynd Zuse um áætlunarframleiðslutæki var hugmynd Heinz Rutishauser [9] um sjálfvirka útreikninga áætlunarframleiðslu. Í fyrirlestri sem haldinn var fyrir Society for Applied Mathematics and Mechanics ( GAMM ) sem og í habilitation ritgerð sinni við ETH Zurich árið 1951, lýsti hann hvaða viðbótarforritunarskipanir (leiðbeiningar) og vélbúnaðarviðbætur væru nauðsynlegar við Z4, sem síðan var notuð á ETHZ Tölvan er einnig hægt að nota sem aðstoð við sjálfvirka gerð forrita. [10] [11] [12]
Snemma þýðanda var hannað af stærðfræðingnum Grace Hopper árið 1949. Fram að þeim tíma þurftu forritarar að búa til vélakóða beint. (Fyrsti samsetjandinn var saminn af Nathaniel Rochester fyrir IBM 701 á árunum 1948 til 1950.) Til að einfalda þetta ferli þróaði Grace Hopper aðferð sem gerði það mögulegt að búa til forrit og undirúrræði þeirra á mannlegri en vélrænan hátt stilltan hátt að tjá. [13] Hinn 3. maí 1952 kynnti Hopper fyrsta þýðandann A-0 áður en reiknirit úr vörulista var afturkallað, endurskrifaði kóða sem var safnað í réttri röð, frátekið pláss og úthlutun minni vistföng skipulögð. [14] Í upphafi árs 1955 kynnti Hopper frumgerð af þýðandanum B-0 , sem bjó til forrit samkvæmt enskum, frönskum eða þýskum fyrirmælum. [15] Hopper kallaði erindi sitt um fyrsta þýðandann „The Education of a Computer“.
Saga smíði þýðanda mótaðist af núverandi forritunarmálum (sjá dagskrá forritunarmála ) og vélbúnaðararkitektúr. Aðrir fyrstu áfangar eru fyrsti Fortran þýðandinn árið 1957 og fyrsti COBOL þýðandinn árið 1960. Hins vegar voru margir byggingareiginleikar þýðenda í dag ekki þróaðir fyrr en á sjötta áratugnum.
Í fortíðinni var stundum stundum kallað forrit sem þýðendur sem setja saman undirforrit. [16] Þetta sniðgengur kjarnaverkefni dagskrárgerðar í dag, því að nú á dögum er hægt að setja inn undirritanir með öðrum hætti: Annaðhvort í frumtextanum sjálfum, til dæmis með forvinnslu (sjá einnig forútgáfu ) eða, þegar um er að ræða samsettar íhlutir, með óháður tengill .
Vinnuháttur
Grunnskrefin sem felast í því að þýða frumkóða í markkóða eru:
- Setningafræðipróf
- Athugað er hvort frumkóðinn táknar gilt forrit, þ.e. hvort það samsvarar setningafræði frummálsins . Allar villur sem finnast eru skráðar. Niðurstaðan er milliframsetning á frumkóðanum.
- Greining og hagræðing
- Milliskjárinn er greindur og fínstilltur. Þetta skref er mjög mismunandi að umfangi eftir þýðanda og notendastillingum. Það er allt frá einfaldari hagræðingu til skilvirkni til dagskrárgreiningar .
- Kóði kynslóð
- Fínstillta milliskjárinn er þýddur í samsvarandi skipanir á markmálinu. Ennfremur er hægt að framkvæma markmálssértækar hagræðingar hér.
- Athugið: Nútíma þýðendur (aðallega) búa ekki lengur til kóða sjálfir.
- C ++ með virkri alþjóðlegri hagræðingu: Kóðinn er búinn til við tengingu.
- C # : Kóðinn er búinn til úr sameiginlegum millimálskóða sem myndaður er við samantekt á meðan keyrslutími er af JIT eða NGEN þýðanda .NET umhverfisins.
- sama gildir um önnur tungumál sem nota sameiginlega tungumálamannvirki eins og F # og VB.NET , sjá lista yfir .NET tungumál .
- Java : Kóðinn er búinn til úr Java bæti kóða sem myndaður er við samantekt meðan á keyrslu stendur af Java JIT þýðandanum.
- Kóðarframleiðsla á keyrslutíma gerir kleift:
- hagræðingu þvert á einingar,
- nákvæmar stillingar á markpallinum (kennslusett, aðlögun að getu örgjörva),
- Notkun sniðupplýsinga.
Uppbygging þýðanda
Gerð þýðanda, þ.e. forritun þýðanda, er sjálfstæð grein innan tölvunarfræði .
Nútíma þýðendur eru skipt í mismunandi áföngum sem hver um sig tekur að sér mismunandi undirverkefni þýðandans. Sum þessara fasa er hægt að útfæra sem sjálfstæð forrit (sjá forútgáfu , forvinnslu ). Þau eru framkvæmd í röð . Í grundvallaratriðum er hægt að greina tvo áfanga: framendann (einnig greiningarfasa ), sem greinir frumtextann og notar hann til að búa til eigið setningafræðitré , og bakendann (einnig myndunarfasa ), sem notar það til að búa til markforritið .
Frontend (einnig „greiningarfasi“)
Í framendanum er kóðinn greindur, uppbyggður og athugaður fyrir villur. Það skiptist sjálft í áföng. Tungumál eins og nútíma C ++ leyfa ekki að skipta setningafræðigreiningu í orðfræðilega greiningu, setningafræðilega greiningu og merkingarfræðilega greiningu vegna tvíræðni í málfræði þeirra. Samsetningarmenn þeirra eru að sama skapi flóknir.
Lexísk greining
Orðfræðileg greining skiptir innfluttum frumtexta í orðrænar einingar ( tákn ) af mismunandi gerðum, til dæmis leitarorð , auðkenni , tölur , strengi eða símafyrirtæki . Þessi hluti þýðandans er kallaður tokenizer, skanni eða lexer.
Skanni notar stundum sérstakan skjá til að sleppa hvítu bili ( hvítt bil , þ.e. bil, flipa, línuendi osfrv.) Og athugasemdir .
Annað hlutverk orðfræðilegrar greiningar er að tengja viðurkennd tákn við stöðu þeirra (t.d. línanúmer) í frumtextanum. Ef villur finnast í frumtextanum í frekari greiningarfasanum, sem byggist á táknunum (t.d. af setningafræðilegri eða merkingarlegri merkingu), er hægt að veita villuboðum sem mynduð eru með tilvísun í staðsetningu villunnar.
Lexical villur eru stafir eða strengir sem ekki er hægt að tengja við tákn. Til dæmis leyfa flest forritunarmál ekki auðkenni sem byrja á tölustöfum (t.d. „3foo“).
Setningafræðileg greining
Setningafræðileg greining athugar hvort innflutti frumkóðinn er í réttri uppbyggingu upprunatungunnar sem á að þýða, þ.e. samsvarar samhengislausri setningafræði (málfræði) frummálsins. Inntakinu er breytt í setningafræðitré . Setningafræðileg greiningartækið er einnig þekkt sem greiningartæki . Ef frumkóðinn passar ekki við málfræði upprunatungunnar sendir þáttarinn frá sér setningafræðilega villu . Setningafræðitréið sem er búið til með þessum hætti er merkt með "innihaldi" hnútanna fyrir næsta áfanga (merkingarfræðileg greining); Það þýðir til dæmis að breytuauðkenni og tölur eru sendar ásamt upplýsingum um að þær séu slíkar. Setningafræðileg greining athugar til dæmis hvort sviga séu rétt, þ.e.a.s hverja upphafsfestingu er fylgt eftir með lokategund af sömu gerð, svo og án þess að sviga flækist. Lykilorðin veita einnig ákveðin mannvirki.
Merkingarfræðileg greining
Merkingarfræðileg greining athugar truflanir merkingarfræði , þ.e. skilyrði í forritinu sem fara út fyrir setningafræðilega greiningu. Til dæmis verður venjulega að hafa lýst yfir breytu áður en hún er notuð og úthlutun verður að vera með samhæfum (samhæfum) gagnategundum . Þetta er hægt að gera með hjálp eigindarmálfræði . Hnútar setningafræðitrésins sem myndaður er af þáttaranum eru gefnir eiginleikar sem innihalda upplýsingar. Til dæmis er hægt að búa til lista yfir allar lýstar breytur. Framleiðsla merkingarfræðilegrar greiningar er síðan kölluð skreytt eða kennt setningafræðitré.
Bakendi (einnig „myndunarstig“)
Afturendinn býr til forritakóða markmálsins úr eigna setningafræðitréinu sem framendinn býr til.
Millistigskóða kynslóð
Margir nútíma þýðendur búa til millikóða frá setningafræðitréinu, sem getur þegar verið tiltölulega nálægt vélinni, og framkvæma til dæmis hagræðingu á þessum millikóða. Þetta er sérstaklega gagnlegt fyrir þýðendur sem styðja mörg uppsprettumál eða mismunandi miðapalla . Hér getur millikóði einnig verið skiptisnið.
Hagræðing dagskrár
Millikóði er grundvöllur margra hagræðinga áætlana. Sjá hagræðingu dagskrár .
Kóði kynslóð
Við kóðaöflun er forritakóði markmálsins myndaður annaðhvort beint úr setningafræðitréinu eða úr millikóðanum. Ef markmálið er vélmál getur útkoman verið keyrsluforrit beint eða svokölluð hlutaskrá sem, með því að tengja við keyrslutíma bókasafnið og hugsanlega aðrar hlutaskrár, leiðir til bókasafns eða keyrsluforrits . Allt þetta er framkvæmt af kóða rafallnum, sem er hluti af þýðandakerfinu, stundum sem hluti af þýðandaforritinu, stundum sem sérstakri einingu.
Flokkun á mismunandi gerðum þýðenda
- Innfæddur þýðandi
- Þýðandi sem býr til markmiðskóða fyrir vettvanginn sem hann keyrir sjálfan sig á. Kóðinn er vettvangssértækur.
- Kross þýðandi
- Þýðandi sem keyrir á einum palli og býr til markkóða fyrir annan vettvang, til dæmis annað stýrikerfi eða annan örgjörva arkitektúr .
- Dæmigerð forrit er að búa til forrit fyrir innbyggt kerfi sem sjálft inniheldur engin tæki eða engin góð tæki til að búa til hugbúnað, svo og að búa til eða flytja stýrikerfi á nýjan vettvang.
- Single pass þýðandi
- Þýðandi sem býr til markkóðann úr frumkóðanum í einni leið (öfugt við multi-pass þýðandann); þýðandinn les frumtextann frá framhlið til baka aðeins einu sinni og býr til niðurstöðuforritið á sama tíma. Slík þýðandi er venjulega mjög hröð en getur aðeins framkvæmt einfaldar hagræðingar. Aðeins er hægt að búa til single-pass þýðanda fyrir ákveðin forritunarmál, til dæmis Pascal , C og C ++ , því forritunarmálið má ekki innihalda framvísanir (ekkert má nota sem ekki hefur þegar verið lýst „ofar“ í frumkóða).
- Multi-pass þýðandi
- Með þessari tegund þýðanda er frumkóðinn þýddur í markkóðann í nokkrum skrefum (upphaflega: frumkóðinn er lesinn nokkrum sinnum eða unnið í gegn nokkrum sinnum „frá framan til baka“). Í árdaga smíði þýðanda var þýðingarferlinu aðallega skipt í nokkrar keyrslur vegna þess að tölvan hafði oft ekki næga getu til að geyma heildarútgáfuna og forritið til að þýða í aðalminni á sama tíma. Nú á dögum er multi-pass þýðandi aðallega notaður til að leysa framvísanir ( yfirlýsingu auðkennis "lengra niður í frumkóðanum" sem fyrstu notkun þess) og til að framkvæma flóknar hagræðingar.
Sérstök eyðublöð
- Transcompiler (einnig þekkt sem transpiler eða cross-translator ) er sérstakur þýðandi sem þýðir frumkóða eins forritunarmáls í frumkóða annars forritunarmáls, til dæmis frá Pascal í C. [17] Þetta ferli er kallað „umbreyting kóða“ eða „þýðing“. Hins vegar, þar sem mörg forritunarmál hafa sérstaka eiginleika og afköstareiginleika, getur skilvirkni tapast ef ekki er tekið tillit til þess af umritara. [18] Þar sem forritunarmál fylgja að mestu leyti mismunandi forritunarhugmyndum er nýbúið að búa til frumkóða er oft erfitt að lesa fyrir forritara. Stundum er handvirk eftirvinnsla á kóðanum nauðsynleg þar sem sjálfvirk þýðing virkar ekki snurðulaust í öllum tilfellum. Það eru einnig víðtæk undirforritasöfn á mörgum nútíma forritunarmálum. Að innleiða símtalasöfn gerir samantektarferlið enn erfiðara.
- Þýðandi þýðendur og þýðendur rafala eru hjálparforrit fyrir sjálfvirka kynslóð þýðanda hluta eða fullkomna þýðendur. Sjá einnig: ANTLR , Coco / R , JavaCC , Lex , Yacc
- Just-in-time þýðendur (eða JIT þýðendur ) þýða ekki frumkóða eða millikóða í vélakóða fyrr en forritið er keyrt. Forritahlutir eru aðeins teknir saman þegar þeir eru keyrðir í fyrsta skipti eða nokkrum sinnum. Hæð hagræðingar fer venjulega eftir tíðni notkunar samsvarandi aðgerðar.
- Með túlkinum er frumkóði forritsins fyrst þýddur í millikóða sem síðan er túlkaður við keyrslu. Túlkar ættu að sameina kosti þýðandans við kosti túlksins . Til að stytta framkvæmdartíma eru margir túlkar nútímans í raun innleiddir innbyrðis sem tölvur sem þýða kóðann á keyrslutíma áður en forritið er keyrt. Meðkóða túlkur er einnig þýðandi, t.d. B. sýndarvélarnar frá Java upp í útgáfu 1.2.
Hagræðing dagskrár (í smáatriðum)
Margir hagræðingar sem áður voru verkefni þýðandans eru nú framkvæmdar innan örgjörva meðan kóðinn er í vinnslu. Vélkóði er góður þegar hann hefur stuttar gagnrýnar slóðir og fáar á óvart vegna rangt spáðra stökka, óskar eftir gögnum úr minni í tæka tíð og notar allar framkvæmdareiningar örgjörva jafnt.

Til að stjórna þýðingunni getur frumtextinn innihaldið sérstakar sérstakar leiðbeiningar um þýðanda auk leiðbeininga forritunarmálsins.
Þýðandi býður venjulega upp á valkosti fyrir ýmsar hagræðingar með það að markmiði að bæta keyrslutíma miðaforritsins eða lágmarka kröfur um geymslurými . Hagræðingin er að hluta háð eiginleikum vélbúnaðarins , til dæmis hve margir og hvaða skrár örgjörvi tölvunnar gerir aðgengilega. Það er mögulegt að forrit gangi hægar eftir hagræðingu en það hefði gert án hagræðingar. Þetta getur til dæmis gerst þegar hagræðing fyrir forritagerð framleiðir lengri kóða sem í raun væri keyrður hraðar en þarf lengri tíma til að hlaða í skyndiminnið . Það er því aðeins hagkvæmt ef það er notað oft.
Sumar hagræðingar leiða til þess að þýðandinn býr til markmálsmannvirki sem engin bein ígildi er fyrir í frummálinu. Ókostur við slíka hagræðingu er að þá er varla hægt að fylgja forritaflæðinu með gagnvirkum kembiforriti á upprunatungumálinu.
Hagræðing getur verið mjög tímafrekt. Í mörgum tilfellum, sérstaklega í nútíma JIT þýðendum, er því nauðsynlegt að vega upp hvort það er þess virði að fínstilla hluta af forritinu. Með tímasetningum fyrir tímann eru allar skynsamlegar hagræðingar notaðar í lokasafninu, en oft ekki meðan á hugbúnaðarþróun stendur (þetta styttir tímasetninguna sem þarf). Fyrir ekki sjálfvirka hagræðingu af hálfu forritarans er hægt að keyra próf og atburðarásir (sjá prófíl ) til að komast að því hvar flóknar hagræðingar eru þess virði.
Í eftirfarandi er litið til nokkurra hagræðingarvalkosta fyrir þýðanda . Mestu hagræðingarmöguleikarnir felast þó oft í því að breyta frumforritinu sjálfu, til dæmis í því að skipta út reiknirit fyrir skilvirkari. Í flestum tilfellum er ekki hægt að gera þetta ferli sjálfvirkt, heldur þarf forritarinn að framkvæma það . Á hinn bóginn er hægt að framselja einfaldari hagræðingar til þýðandans til að halda frumkóðanum læsilegum.
Vistun vélskipana
Í mörgum forritunarmálum á háu stigi, til dæmis, þarftu aukabreytu til að skipta um innihald tveggja breytna:
Upprunakóði | Vélskipanir | |
---|---|---|
án hagræðingar | með hagræðingu | |
hilf := a | a → skráning 1 Skráning 1 → hjálp | a → skráning 1 |
a := b | b → Skráning 1 Skráning 1 → a | b → Skrá 2 Skrá 2 → a |
b := hilf | hjálp → Skráning 1 Skráning 1 → b | Skráning 1 → b |
Nauðsynlegt ... | ||
breytur | 3 | 2 |
skrá | 1 | 2 |
Aðgerðir | 6. | 4. |
Með hagræðingu, eru aðeins 4 Assembler skipanir sem þarf í stað 6, og minni fyrir tengd breytu hilf
ekki krafist. Þetta þýðir að þessi skipti eru framkvæmd hraðar og krefjast minna aðalminni . Þetta á þó aðeins við ef nægar skrár eru til staðar í örgjörvanum . Geymsla gagna í skrám í stað aðalminni er algengur hagræðingarkostur.
Skipunarröðin sem sýnd er hér að ofan sem fínstillt hefur aðra eiginleika sem getur verið kostur í nútíma örgjörvum með nokkrum vinnsluleiðslum: Hægt er að vinna úr tveimur skipunum tveimur og skrifskipunum tveimur samhliða án vandræða, þær eru ekki háðar niðurstöðu annað. Aðeins fyrsta skrifskipunin verður örugglega að bíða þar til síðasta lestrarskipunin hefur verið framkvæmd. Ítarlegri hagræðingarferli geta því sett vélskipanir á milli b → register 2 og register 2 → a sem tilheyra allt annarri háskipta stjórnlínu.
Static formúlumat á samantektartíma
Útreikningur á ummáli með því að nota
pi = 3.14159
u = 2 * pi * r
getur þýðandi þegar á samantektartíma til að u = 6.28318 * r
meta. Þetta formúlumat bjargar margfölduninni 2 * pi
meðan keyrslutími mynda forritsins stendur yfir. Þessi aðferð er kölluð stöðug felling.
Útrýming dauðs forritakóða
Ef þýðandinn getur viðurkennt að hluti af forritinu verður aldrei keyrður í gegnum, þá getur hann sleppt þessum hluta úr samantektinni.
Dæmi:
100 fara til 900
200 k = 3
900 ég = 7
... ...
Ef það er aldrei GOTO
á stökkmerki 200
í þessu forriti er 200 k=3
sleppa leiðbeiningunum 200 k=3
. Stökkkennslan 100 goto 900
er þá líka óþörf.
Greining á ónotuðum breytum
Ef breytu er ekki krafist þarf ekkert minnispláss að vera frátekið fyrir hana og ekki þarf að búa til markkóða.
Dæmi:
subroutine próf (a, b)
b = 2 * a
c = 3,14 * b
skila b
Breytan c
ekki krafist hér: Hún er ekki á breytulistanum , er ekki notuð í síðari útreikningum og er ekki gefin út. Þess vegna c = 3.14 * b
sleppa kennslunni c = 3.14 * b
.
Hagræða lykkjur
Sérstaklega reynir maður að fínstilla lykkjur með því til dæmis
- geymir eins margar breytur og mögulegt er í skrám (venjulega að minnsta kosti lykkjubreytu);
- í stað vísitölu, með þætti sviðs ( enska er nálægur fylki), vísbendingar sem notaðar eru til frumefnanna, einkenndu viðleitni til að fá aðgang að sviðseiningum er lítil;
- Útreikningar innan lykkjunnar, sem framleiða sömu niðurstöðu í hverri keyrslu, eru aðeins gerðar einu sinni fyrir lykkjuna (lykkja-óbreytanleg kóða hreyfing);
- sameinar tvær lykkjur sem ná yfir sama gildissvið í eina lykkju, þannig að stjórnsýsluátak fyrir lykkjuna verður aðeins einu sinni;
- lykkjan að hluta eða (þegar um lykkjur er að ræða með föstum, lágum fjölda sendinga) afrullast alveg (enska lykkja afrullast ), þannig að leiðbeiningar innan lykkjunnar eru framkvæmdar nokkrum sinnum í beinni röð án þess að athuga ástand lykkju og stökkva til upphafs lykkjunnar sem fer fram hverju sinni eftir leiðbeiningunum;
- snýr lykkjunni við (sérstaklega með talnalykkjum með fyrir ), þar sem hægt er að nota skilvirkar stökkskipanir (Jump-Not-Zero) þegar talið er niður í 0;
- endurmótar lykkjuna þannig að athugun á uppsagnarástandi fer fram í lok lykkjunnar (lykkjur með upphaflegri athugun hafa alltaf skilyrt og skilyrðislaus stökkfyrirmæli, en lykkjur með lokaprófi hafa aðeins skilyrt stökkkennslu);
- fjarlægði alla lykkjuna ef (eftir nokkrar klip) hefur hún tóman líkama. Hins vegar getur þetta leitt til þess að biðraðir sem ætlað er að hægja á forriti eru fjarlægðar. Hins vegar ætti að nota aðgerðir stýrikerfisins í þessu skyni eins og kostur er.
- Raðar hreiður lykkjur (lykkjur í lykkjum) - ef forritunarrökfræði sem notuð er leyfir það - í hækkandi röð, frá ystu lykkju með fæstum lykkjum til innstu lykkju með flestum lykkjum. Þetta kemur í veg fyrir að margar frumstilla innri lykkjulíkama.
Sumar af þessum hagræðingum eru gagnslausar eða jafnvel gagnlegar við núverandi örgjörva.
Innsetning undirrita
Þegar um er að ræða litlar undiráætlanir er áreynslan sem þarf til að kalla undirrútínuna mikilvægari en sú vinna sem unnin er af undirrútínunni. Vistþýðendur því að reyna að setja vél kóða smærri subroutines beint - svipaðar hvernig sumir Þýðendur / vélgæslufólk / precompilers brjóta niður þjóðhagsleg leiðbeiningar inn kóða. Þessi tækni er einnig þekkt sem inlining. Á sumum forritunarmálum er hægt að nota innfelld leitarorð til að gefa þýðandanum til kynna að setja ætti inn ákveðnar undirleiðir. Innsetning undirrita opnar oft frekari möguleika á hagræðingu, allt eftir breytum.
Að halda gildum í skrám
Anstatt mehrfach auf dieselbe Variable im Speicher, beispielsweise in einer Datenstruktur, zuzugreifen, kann der Wert nur einmal gelesen und für weitere Verarbeitungen in Registern oder im Stack zwischengespeichert werden. In C , C++ und Java muss dieses Verhalten ggf. mit dem Schlüsselwort volatile abgeschaltet werden: Eine als volatile bezeichnete Variable wird bei jeder Benutzung wiederholt vom originalen Speicherplatz gelesen, da ihr Wert sich unterdessen geändert haben könnte. Das kann beispielsweise der Fall sein, wenn es sich um einen Hardware-Port handelt oder ein parallel laufender Thread den Wert geändert haben könnte.
Beispiel:
int a = array [ 25 ] -> element . x ;
int b = 3 * array [ 25 ] -> element . x ;
Im Maschinenprogramm wird nur einmal auf array[25]->element.x
zugegriffen, der Wert wird zwischengespeichert und zweimal verwendet. Ist x
volatile, dann wird zweimal zugegriffen.
Es gibt außer volatile noch einen anderen Grund, der eine Zwischenspeicherung in Registern unmöglich macht: Wenn der Wert der Variablen v
durch Verwendung des Zeigers z
im Speicher verändert werden könnte, kann eine Zwischenspeicherung von v
in einem Register zu fehlerhaftem Programmverhalten führen. Da die in der Programmiersprache C oft verwendeten Zeiger nicht auf ein Array beschränkt sind (sie könnten irgendwohin im Hauptspeicher zeigen), hat der Optimizer oft nicht genügend Informationen, um eine Veränderung einer Variablen durch einen Zeiger auszuschließen.
Verwendung schnellerer äquivalenter Anweisungen
Statt einer Multiplikation oder Division von Ganzzahlen mit einer Zweierpotenz kann ein Schiebebefehl verwendet werden. Es gibt Fälle, in denen nicht nur Zweierpotenzen, sondern auch andere Zahlen (einfache Summen von Zweierpotenzen) für diese Optimierung herangezogen werden. So kann zum Beispiel ( n << 1 ) + ( n << 2 )
schneller sein als n * 6
. Statt einer Division durch eine Konstante kann eine Multiplikation mit dem Reziprokwert der Konstante erfolgen. Selbstverständlich sollte man solch spezielle Optimierungen auf jeden Fall dem Compiler überlassen.
Weglassen von Laufzeitüberprüfungen
Programmiersprachen wie Java fordern Laufzeitüberprüfungen beim Zugriff auf Felder oder Variablen. Wenn der Compiler ermittelt, dass ein bestimmter Zugriff immer im erlaubten Bereich sein wird (zum Beispiel ein Zeiger, von dem bekannt ist, dass er an dieser Stelle nicht NULL ist), kann der Code für diese Laufzeitüberprüfungen weggelassen werden.
Reduktion von Paging zur Laufzeit
Eng zusammenhängende Codebereiche, zum Beispiel ein Schleifenrumpf, sollte zur Laufzeit möglichst auf der gleichen oder in möglichst wenigen Speicherseiten („Page“, zusammenhängend vom Betriebssystem verwalteter Speicherblock) im Hauptspeicher liegen. Diese Optimierung ist Aufgabe des (optimierenden) Linkers. Dies kann zum Beispiel dadurch erreicht werden, dass dem Zielcode an geeigneter Stelle Leeranweisungen („NOPs“ – N o OP eration) hinzugefügt werden. Dadurch wird der erzeugte Code zwar größer, aber wegen der reduzierten Anzahl notwendiger TLB-Cache-Einträge und notwendiger Pagewalks wird das Programm schneller ausgeführt.
Vorziehen bzw. Verzögern von Speicherzugriffen
Durch das Vorziehen von Speicherlesezugriffen und das Verzögern von Schreibzugriffen lässt sich die Fähigkeit moderner Prozessoren zur Parallelarbeit verschiedener Funktionseinheiten ausnutzen. So kann beispielsweise bei den Befehlen: a = b * c; d = e * f;
der Operand e
bereits geladen werden, während ein anderer Teil des Prozessors noch mit der ersten Multiplikation beschäftigt ist.
Ein Beispielcompiler
Folgendes in ANTLR erstelltes Beispiel soll die Zusammenarbeit zwischen Parser und Lexer erklären. Der Übersetzer soll Ausdrücke der Grundrechenarten beherrschen und vergleichen können. Die Parser grammatik wandelt einen Dateiinhalt in einen abstrakten Syntaxbaum (AST) um.
Grammatiken
Die Baumgrammatik ist in der Lage, die im AST gespeicherten Lexeme zu evaluieren. Der Operator der Rechenfunktionen steht in der AST-Schreibweise vor den Operanden als Präfixnotation . Daher kann die Grammatik ohne Sprünge Berechnungen anhand des Operators durchführen und dennoch Klammerausdrücke und Operationen verschiedener Priorität korrekt berechnen.
tree grammar Eval ;
options {
tokenVocab = Expression ;
ASTLabelType = CommonTree ;
}
@header {
import java.lang.Math ;
}
start : line + ; //Eine Datei besteht aus mehreren Zeilen
line : compare { System . out . println ( $compare . value );}
;
compare returns [ double value ]
: ^ ( '+' a = compare b = compare ) { $value = a + b ;}
| ^ ( '-' a = compare b = compare ) { $value = a - b ;}
| ^ ( '*' a = compare b = compare ) { $value = a * b ;}
| ^ ( '/' a = compare b = compare ) { $value = a / b ;}
| ^ ( '%' a = compare b = compare ) { $value = a \ % b ;}
| ^ ( UMINUS a = compare ) { $value = - 1 * a ;} //Token UMINUS ist notwendig, um den binären
//Operator nicht mit einem Vorzeichen zu verwechseln
| ^ ( '^' a = compare b = compare ) { $value = Math . pow ( a , b );}
| ^ ( '=' a = compare b = compare ) { $value = ( a == b ) ? 1 : 0 ;} //wahr=1, falsch=0
| INT { $value = Integer . parseInt ( $INT . text );}
;
Ist eines der oben als compare bezeichnete Ausdrücke noch kein Lexem, so wird es von der folgenden Lexer-Grammatik in einzelne Lexeme aufgeteilt. Dabei bedient sich der Lexer der Technik des rekursiven Abstiegs . Ausdrücke werden so immer weiter zerlegt, bis es sich nur noch um Token vom Typ number oder Operatoren handeln kann.
grammar Expression ;
options {
output = AST ;
ASTLabelType = CommonTree ;
}
tokens {
UMINUS ;
}
start : ( line { System . out . println ( $line . tree == null ? "null" : $line . tree . toStringTree ());}) + ;
line : compare NEWLINE -> ^ ( compare ); //Eine Zeile besteht aus einem Ausdruck und einem
//terminalen Zeichen
compare : sum ( '=' ^ sum ) ? ; //Summen sind mit Summen vergleichbar
sum : product ( '+' ^ product | '-' ^ product ) * ; //Summen bestehen aus Produkten (Operatorrangfolge)
product : pow ( '*' ^ pow | '/' ^ pow | '%' ^ pow ) * ; //Produkte (Modulo-Operation gehört hier dazu) können
//aus Potenzen zusammengesetzt sein
pow : term ( '^' ^ pow ) ? ; //Potenzen werden auf Terme angewendet
term : number //Terme bestehen aus Nummern, Subtermen oder Summen
| '+' term -> term
| '-' term -> ^ ( UMINUS term ) //Subterm mit Vorzeichen
| '(' ! sum ')' ! //Subterm mit Klammerausdruck
;
number : INT ; //Nummern bestehen nur aus Zahlen
INT : '0' .. '9' + ;
NEWLINE : '\r' ? '\n' ;
WS : ( ' ' | '\t' | '\n' | '\r' ) + { skip ();}; //Whitespace wird ignoriert
Die Ausgabe hinter dem Token start zeigt außerdem den gerade evaluierten Ausdruck.
Ausgabe des Beispiels
Eingabe:
5 = 2 + 3 32 * 2 + 8 (2 * 2^3 + 2) / 3
Ausgabe (in den ersten Zeilen wird nur der Ausdruck der Eingabe in der AST-Darstellung ausgegeben):
(= 5 (+ 2 3)) (+ (* 32 2) 8) (/ (+ (* 2 (^ 2 3)) 2) 3) 1.0 72.0 6.0
Der erste Ausdruck wird also als wahr (1) evaluiert, bei den anderen Ausdrücken wird das Ergebnis der Rechnung ausgegeben.
Literatur
- Alfred V. Aho , Monica S. Lam, Ravi Sethi, Jeffrey D. Ullman : Compilers: principles, techniques, & tools . Pearson Addison-Wesley, Boston 2007, ISBN 0-321-48681-1 .
- Alfred V. Aho, Monica S. Lam, Ravi Sethi, Jeffrey D. Ullman: Compiler . Pearson, 2008, ISBN 978-3-8273-7097-6 (Deutsche Übersetzung).
- Reinhard Wilhelm , Dieter Maurer: Übersetzerbau – Theorie, Konstruktion, Generierung . Springer, 1997, ISBN 3-540-61692-6 .
- Niklaus Wirth : Grundlagen und Techniken des Compilerbaus . 3., bearbeitete Auflage. Oldenbourg Wissenschaftsverlag, München 2011, ISBN 978-3-486-70951-3 .
Weblinks
Einzelnachweise
- ↑ Michael Eulenstein: Generierung portabler Compiler. Das portable System POCO. (= Informatik-Fachberichte 164) Springer Verlag: Berlin, ua, 1988, S. 1; Hans-Jochen Schneider (Hrsg.): Lexikon Informatik und Datenverarbeitung. 4. Auflage, Oldenbourg Verlag: München, Berlin, 1998, 900; Manfred Broy: Informatik. Eine grundlegende Einführung. Band 2: Systemstrukturen und Theoretische Informatik. 2. Auflage, Springer Verlag: Berlin, Heidelberg, 1998, S. 173.
- ↑ a b Carsten Busch: Mataphern in der Informatik. Modellbildung - Formalisierung - Anwendung. Springer Fachmedien: Wiesbaden, 1998, S. 171.
- ↑ Axel Rogat: Aufbau und Arbeitsweise von Compilern , Kapitel 1.11: Geschichte ; Thomas W. Parsons: Introduction to Compiler Construction. Computer Science Press: New York, 1992, S. 1.
- ↑ Zur Übersetzung des englischen „compiler“ mit dem deutschen „Übersetzer“ siehe ua: Hans-Jürgen Siegert, Uwe Baumgarten: Betriebssysteme. Eine Einführung. 6. Auflage, Oldenbourg Verlag: München, Wien, 2007, S. 352; Christoph Prevezanos: Computer-Lexikon 2011. Markt+Technik Verlag: München, 2010, S. 940; Christoph Prevenzanos: Technisches Schreiben. Für Informatiker, Akademiker, Techniker und den Berufsalltag. Hanser Verlag: München, 2013, S. 130.
- ↑ So beispielsweise Alfred V. Aho, Monica S. Lam, Ravi Sethi, Jeffrey D. Ullman: Compiler. Prinzipien, Techniken und Werkzeuge. 2. Auflage, Pearson Studium: München, 2008.
- ↑ Siehe dazu Hans-Jochen Schneider (Hrsg.): Lexikon Informatik und Datenverarbeitung. 4. Auflage, Oldenbourg Verlag: München, Berlin, 1998: Artikel „Compiler“, S. 158, und Artikel „Übersetzer“, S. 900.
- ↑ Hartmut Ernst, Jochen Schmidt; Gert Beneken: Grundkurs Informatik. Grundlagen und Konzepte für die erfolgreiche IT-Praxis. Eine umfassende, praxisorientierte Einführung. 5. Auflage, Springer: Wiesbaden, 2015, S. 409.
- ↑ Hans Dieter Hellige: Geschichten der Informatik. Visionen, Paradigmen, Leitmotive. Springer, Berlin 2004, ISBN 3-540-00217-0 , S. 45, 104, 105.
- ↑ Evelyn Boesch Trüeb: Heinz Rutishauser. In: Historisches Lexikon der Schweiz . 12. Juli 2010 , abgerufen am 21. Oktober 2014 .
- ↑ Stefan Betschon: Der Zauber des Anfangs. Schweizer Computerpioniere. In: Franz Betschon , Stefan Betschon, Jürg Lindecker, Willy Schlachter (Hrsg.): Ingenieure bauen die Schweiz. Technikgeschichte aus erster Hand. Verlag Neue Zürcher Zeitung, Zürich 2013, ISBN 978-3-03823-791-4 , S. 381–383.
- ↑ Friedrich L. Bauer: My years with Rutishauser.
- ↑ Stefan Betschon: Die Geschichte der Zukunft. In: Neue Zürcher Zeitung, 6. Dezember 2016, S. 11
- ↑ Inventor of the Week Archive.Massachusetts Institute of Technology , Juni 2006, abgerufen am 25. September 2011 .
- ↑ Kurt W. Beyer: Grace Hopper and the invention of the information age . Massachusetts Institute of Technology, 2009, ISBN 978-0-262-01310-9 ( Google Books [abgerufen am 25. September 2011]).
- ↑ Kathleen Broome Williams: Grace Hopper . Naval Institute Press, 2004, ISBN 1-55750-952-2 ( Google Books [abgerufen am 25. September 2011]).
- ↑ FL Bauer, J. Eickel: Compiler Construction: An Advanced Course . Springer, 1975.
- ↑ Transcompiler. In: Neogrid IT Lexikon. Abgerufen am 18. November 2011 : „Wenn ein Compiler aus dem Quellcode einer Programmiersprache den Quellcode einer anderen erzeugt (z. B. C in C++) so spricht man von einem Transcompiler.“
- ↑ Transpiler. bullhost.de, abgerufen am 18. November 2012 .