Jeffrey Cross
Jeffrey Cross

Duffin laite: silmukan poistaminen tulkituista kielistä

Vuonna 1983 Tom Duff keksi todella kummallisen tavan käyttää C-kielen kytkin- ja kotelotilannetta suurten silmukoiden in-code “unrolling” optimoinnissa. Esimerkiksi hän kuvaili yksinkertaisen silmukan, joka kopioi taulukon tulostusrekisteriin:

lähetä (mistä, laskee) rekisteriin lyhyt * -, * alkaen; rekisterin määrä; {do * = = * ++: sta; while (- count> 0); }

Silmukan jokaisella iteraatiolla suoritettavan kopion lisäksi laskentamuuttuja pienennetään ja vertailu tehdään 0. Duffin laitteella voit saavuttaa saman tuloksen, mutta vain kahdeksannen yläpuolella:

lähetä (mistä, laskee) rekisteriin lyhyt * -, * alkaen; rekisterin määrä; {rekisteri n = (count + 7) / 8; kytkin (count% 8) {case 0: do {* = = * ++; tapaus 7: * = = * ++; tapaus 6: * = = * ++; tapaus 5: * = = * ++; tapaus 4: * = = * ++; tapaus 3: * = = * ++; tapaus 2: * = = * ++; tapaus 1: * = = * ++; } Kun taas (- n> 0); }}

Mitä tapahtuu, että silmukka aukeaa 8 kertaa, joten silmukan jokainen iterointi kulkee sisäistä koodia 8 kertaa ilman vertailua. Duffin laitteen nero on se, että se hyödyntää tapaa, jolla C-kytkin / kotelorakenne toimii. Ensimmäistä kertaa, jos iteraatiot eivät jakaudu tasaisesti 8: een, silmukan koodi suoritetaan riittävän monta kertaa, jotta se vastaa jäljellä olevia iteraatioita / 8.Se on hieman outo, koska "do" -lausuma tapahtuu kytkimen sisällä, mutta "do" -kohdassa on "case" - lausuntoja. Se on kuitenkin voimassa C.

Ennen kuin joku huutaa epämiellyttävää, muista, että tämä sopii vain sisäisten silmukoiden suorituskyvyn nopeuttamiseen, kun sopiva, parempi algoritmi ei ole käytettävissä. Jos koodit C, nykyaikaisimmat kääntäjät ovat tarpeeksi älykkäitä, jotta koodisi voidaan automaattisesti optimoida ja silmukoita avata.

Jos tulkitset kieliä, kuten PHP tai Javascript, sinun täytyy joskus tehdä vähän optimointia, jos haluat puristaa joitakin ylimääräisiä tuloksia. Onneksi molemmilla kielillä on c-tyylinen kytkin.

Andy King kirjoitti hieman muutetusta versiosta tämän silmukan unrolling-algoritmista, joka ojentaa kytkentälausuman ja rikkoo normaalin Duffin laitteen kahteen erilliseen silmukkaan, joista toinen on loput ja toinen poistamiseen. Javascriptissä se suorittaa yksinkertaisen lisäsilmukan vain kolmanneksella normaalin silmukan ajasta (testVal ++ on normaali silmukan sisustus):

toiminto duffFasterLoop8 (iteraatiot) {var testVal = 0; var n = iteraatiot% 8; jos (n> 0) {do {testVal ++; } kun (--n); // n: n tulee olla suurempi kuin 0 täällä} n = parseInt (iteraatiot / 8); tee {testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; } kun (--n); }

Se ei ole yhtä synteettinen kuin Duffin laite, mutta se on hyvä tapa poistaa sisäinen silmukka manuaalisesti ja saada paras suorituskyky ylimääräistä vaivaa varten.

Duffin laitteen Andy Kingin optimointi JavaScriptin suorittamiseen

Osake

Jättänyt Kommenttia