Netværk-Ullman algoritme | |
---|---|
Opkaldt efter | Ravi Sethi [d] ogJeffrey Ullman |
formål | søge efter den optimale oversættelsesrækkefølge for et udtryk |
Datastruktur | kurve |
Network-Ullman- algoritmen er en algoritme til at oversætte abstrakte syntakstræer til maskinkode, der bruger så få registre som muligt . Algoritmen er opkaldt efter dens udviklere Ravi Seti og Jeffrey Ullman ,
Når der genereres kode til aritmetiske udtryk , skal compileren beslutte, hvilken der er den bedste måde at oversætte udtrykket på i forhold til antallet af brugte instruktioner, samt antallet af registre, der er nødvendige for at evaluere et bestemt undertræ. Især i det tilfælde, hvor antallet af frie registre er lille, kan rækkefølgen af eksekvering være vigtig for længden af den genererede kode, da en anden evalueringsrækkefølge kan resultere i mere eller mindre mellemværdier, der bliver smidt ud i hukommelsen og derefter genoprettet. Network-Ullman-algoritmen (også kendt som Network-Ullmann-nummerering ) har den egenskab, at den producerer kode, der kræver det mindste antal instruktioner såvel som det mindste antal hukommelsesreferencer (forudsat at operationerne i det mindste er kommutative og associative , men distributiv lov , dvs. ikke udføres). Bemærk, at algoritmen lykkes, selvom hverken kommutativitet eller associativitet finder sted i udtrykket, og derfor kan aritmetiske transformationer ikke anvendes. Algoritmen bruger heller ikke almindelig detektering af underudtryk eller eksplicit brug af generelle rettede acykliske grafer i stedet for træer.
Simple Network-Ullmann-algoritmen fungerer som følger (for load/store -arkitekturen ):
For et aritmetisk udtryk ser det abstrakte syntakstræ således ud:
= / \ en* / \ / \ ++ /\/\ /\d3 + * /\/\ bcfgFor at udføre algoritmen skal vi kun tjekke det aritmetiske udtryk , dvs. vi behøver kun at se på det højre undertræ af '=' destinationen:
* / \ / \ ++ /\/\ /\d3 + * /\/\ bcfgVi starter nu trævandringen ved at tildele antallet af registre, der skal til for at evaluere hvert undertræ (bemærk, at det sidste led i udtrykket er en konstant):
* 2 / \ / \ + 2 + 1 /\/\ / \ d 1 3 0 + 1 * 1 /\/\ b 1 c 0 f 1 g 0Fra dette træ kan du se, at vi har brug for 2 registre for at beregne det venstre undertræ af '*', men kun behøver et register for at beregne det højre undertræ. Noderne 'c' og 'g' behøver ikke registre af følgende årsager: Hvis T er et blad af træet, så er antallet af registre til at evaluere T enten 1 eller 0 afhængigt af om T er i venstre eller højre undertræ (fordi operationer som f.eks. tilføje R1, A kan behandle den rigtige komponent af A direkte uden at registrere den). Derfor bør vi starte med at udføre det venstre undertræ, da vi kan ende med en situation, hvor vi kun har to registre til at evaluere hele udtrykket. Hvis vi først beregner det højre undertræ (som kun kræver et register), skal vi gemme resultatet af det højre undertræ, mens vi beregner det venstre undertræ (som stadig har brug for 2 registre), så 3 registre er nødvendige. Evalueringen af det venstre undertræ kræver to registre, men resultatet kan gemmes i ét register, og da det højre undertræ kræver et register for at evaluere, kan udtrykket evalueres med kun to registre.
I en forbedret version af Network-Ullman-algoritmen konverteres aritmetiske udtryk først ved hjælp af de aritmetiske egenskaber for de anvendte operatorer.