Saturday 16 December 2017

Moving genomsnittet effektiv implementering


Forskaren och ingenjörsguiden till digital signalbehandling av Steven W. Smith, Ph. D. Kapitel 24: Linjär bildbehandlingskonvolution genom separabilitet Detta är en teknik för snabb konvolvering, så länge som PSF-enheten är separerbar. En PSF sägs vara separerbar om den kan brytas in i två endimensionella signaler: en vertikal och ett horisontellt projektion. Figur 24-5 visar ett exempel på en separerbar bild, den fyrkantiga PSF. Specifikt är värdet för varje pixel i bilden lika med motsvarande punkt i det horisontella projektionen multiplicerat med motsvarande punkt i det vertikala utsprånget. I matematisk form: där x r, c är den tvådimensionella bilden, och vert r amp horz c är de endimensionella projektionerna. Självklart uppfyller de flesta bilderna inte detta krav. Till exempel är pillboxen inte separerbar. Det finns emellertid ett oändligt antal separerbara bilder. Detta kan förstås genom att generera godtyckliga horisontella och vertikala utsprång och hitta den bild som motsvarar dem. Exempelvis illustrerar Fig. 24-6 detta med profiler som är dubbelsidiga exponentialer. Bilden som motsvarar dessa profiler hittas sedan från ekv. 24-1. När bilden visas, visas bilden som en diamantform som exponentiellt sönderfaller till noll då avståndet från ursprunget ökar. I de flesta bildbehandlingsuppgifter är den perfekta PSF cirkulärt symmetrisk. såsom pillboxen. Även om digitaliserade bilder vanligtvis lagras och bearbetas i rektangulärt format i rader och kolumner, är det önskvärt att ändra bilden på samma sätt i alla riktningar. Detta väcker frågan: Finns det en PSF som är cirkulärt symmetrisk och separerbar Svaret är ja, men det finns bara en, den gaussiska. Såsom framgår av Fig. 24-7 har en tvådimensionell gaussisk bild projektioner som också är gaussier. Bild - och projektionen Gaussianer har samma standardavvikelse. För att sammanfoga en bild med en separerbar filterkärna, sammanfoga varje rad i bilden med den horisontella projektionen. vilket resulterar i en mellanbild. Därefter sammanfogar varje kolumn med denna mellanbild med den vertikala projektionen av PSF. Den resulterande bilden är identisk med den direkta fällningen av originalbilden och filterkärnan. Om du vill, samla kolumnerna först och sedan raderna blir resultatet detsamma. Konfolutionen av en N-gånger N-bild med en M-gånger-M-filterkärna kräver en tid som är proportional med N 2 M 2. Med andra ord beror varje pixel i utmatningsbilden på alla pixlar i filterkärnan. I jämförelse kräver sammandragning genom separerbarhet endast en tid som är proportionell mot N2M. För filterkärnor som är hundratals pixlar breda, kommer denna teknik att minska genomförandetiden med en hundratals faktor. Saker kan bli ännu bättre. Om du är villig att använda en rektangulär PSF (Fig. 24-5) eller en dubbelsidig exponentiell PSF (Fig. 24-6), är beräkningarna ännu effektivare. Detta beror på att de endimensionella omvälvningarna är det glidande medelfiltret (kapitel 15) respektive det dubbelriktade polsparfiltret (kapitel 19). Båda dessa ettdimensionella filter kan snabbt utföras genom rekursion. Detta resulterar i en bildkonvolutions tid proportionell med endast N 2. Fullständigt oberoende av PSF: s storlek. Med andra ord kan en bild samlas med så stor en PSF som behövs, med bara några heltalsoperationer per bildpunkt. Till exempel kräver konvertering av en 512 x 512 bild endast några hundra millisekunder på en persondator. Det är snabbt. Inte som formen på dessa två filterkärnor. Konvolvera bilden med en av dem flera gånger för att approximera en Gaussisk PSF (garanterad av Central Limit Theorem, Kapitel 7). Det här är bra algoritmer, som klarar av att lyckas med misslyckande käkar. De är väl värda att komma ihåg. MOVING FORTH Del 1: Designbeslut i framåtkärnan av Brad Rodriguez Denna artikel uppträdde först i The Computer Journal 59 (januari februari 1993). INLEDNING Alla i Forth community talar om hur lätt det är att porta fram till en ny CPU. Men som många quoteasyquot - och quotobviousquot-uppgifter, skrivs inte mycket om hur man gör det. Så när Bill Kibler föreslog det här ämnet för en artikel bestämde jag mig för att bryta med den stora muntliga traditionen av författare och dokumentera processen i svartvitt. Under dessa artiklar kommer jag att utveckla Forths för 6809, 8051 och Z80. Jag gör 6809 för att illustrera en enkel och konventionell Forth-modell plus, Ive publicerade redan en 6809 assembler ROD91, ROD92 och Ill behöver en 6809 Forth för framtida TCJ-projekt. Jag gör 8051 Forth för ett universitetsprojekt, men det illustrerar också några ganska olika designbeslut. Z80 Forth är för alla CPM-läsare av TCJ, och för några vänner med TRS-80s som samlar damm. ESSENTIAL HARDWARE Du måste välja en CPU. Jag kommer inte att dyka in i fördelarna med en CPU över en annan för Forth, eftersom en CPU-val vanligtvis är tvungen på dig av andra överväganden. Dessutom är syftet med den här artikeln att visa hur man flyttar fram till en CPU. Du kan förvänta dig den vanliga 16-bitars framåtkärnan (se nedan) för att uppta cirka 8K byte av programutrymme. För en fullständig kärna som kan kompilera Forth-definitioner, bör du tillåta minst 1 K byte RAM. För att använda Forths block management system för disklagring, bör du lägga till 3 Kbytes eller mer för buffertar. För en 32-bitars Forth-modell, dubbelklara dessa siffror. Det här är minsta möjliga för att få en fortsatt kärnkörning. För att köra en applikation på hårdvaran bör du öka PROM och RAM-storlekarna för att passa. 16 ELLER 32 BIT Ordstorleken som används av Forth är inte nödvändigtvis densamma som för CPU. Den minsta praktiska Forth är en 16-bitars modell, dvs en som använder 16-bitars heltal och 16-bitars adresser. Forth community kallar detta kvotcellquotstorleken, eftersom quotwordquot refererar till en vidare definition. 8-bitars processorer stöder nästan alltid 16-bitars framåt. Detta kräver vanligtvis explicit kodning av dubbelbyte-aritmetik, även om vissa 8-bitars CPU-enheter har några 16-bitarsoperationer. 16-bitars CPU körs vanligtvis 16 bitars framåt, även om samma dubbla precisionstekniker kan användas för att skriva en 32-bitars framåt på en 16-bitars CPU. Minst en 32-bitars Forth har skrivits för 80868088. 32-bitars CPU kör normalt 32-bitars Forths. En mindre Forth-modell sällan sparar kodlängd eller processortid. Jag vet emellertid om minst en 16-bitars Forth-skrivning för 68000. Det minskar programkodstorleken med en faktor på två, eftersom avancerade Forth-definitioner blir en sträng med 16-bitars adresser snarare än en sträng av 32- bitadresser. (Detta kommer att bli uppenbart inom kort.) De flesta 68000-tal har dock gott om RAM. Alla exemplen som beskrivs i den här artikeln är 16 bitars framåt som körs på 8-bitars CPU: er. TRÄDNINGSTEKNIKEN citerad kodquot är kännetecknet för Forth. En vidare quotthreadquot är bara en lista över adresser till rutiner som ska utföras. Du kan tänka på detta som en lista över subrutin samtal, med CALL instruktioner borttagen. Under åren har många dragvariationer utformats, och vilken som är bäst beror på processorn och applikationen. För att fatta beslut måste du förstå hur de fungerar, och deras kompromisser. Indirekt trådad kod (ITC) Detta är den klassiska Forth-trådertekniken, som används i figurerna Forth och F83, och beskrivs i de flesta böcker på Forth. Alla andra trådlösa system är quotimprovementsquot på detta, så du behöver förstå ITC för att uppskatta de andra. Låt oss se på definitionen av ett framåtgående ord SQUARE: I en typisk ITC Forth visas detta i minnet som visas i Figur 1. (Rubriken kommer att diskuteras i en framtida artikel, den innehåller hushållsinformation som används för sammanställning och är inte inblandad i gängning .) Antag att SQUARE stöter på att exekvera något annat Forth ord. Future Interpreter Pointer (IP) kommer att peka på en cell i minnet - som ingår i det kvoterotet - som innehåller adressen till ordet SQUARE. (För att vara exakt, innehåller den cellen adressen till SQUAREs Code Field.) Tolken hämtar den adressen och använder den för att hämta innehållet i SQUAREs Code Field. Dessa innehåll är ännu en adress - adressen till en maskinspråkunderrutin som utför ordet SQUARE. I pseudokod är det här: Detta illustrerar en viktig men sällan upplyst princip: Adressen till det fortsatta ordet som just har angetts behålls i W. CODE-ord behöver inte denna information, men alla andra typer av Forth ord gör. Om SQUARE skrevs i maskinkod skulle detta vara slutet på berättelsen: den här maskinkoden skulle exekveras och sedan hoppa tillbaka till Forth interpreter - som, sedan IP inkrementer, pekar på nästa ord till exekveras. Därför kallas den främre tolken vanligtvis NEXT. Men, SQUARE är en högkvalitativ quotcolonquot-definition - den innehåller en quotthreadquot, en lista över adresser. För att kunna utföra denna definition måste den fortsatta tolken startas på nytt på en ny plats: Parameterfältet för SQUARE. Naturligtvis måste tolkarnas gamla plats sparas, för att återuppta kvotkontraktet Framåt ord när SQUARE är färdig. Det här är precis som ett subrutin-samtal SQUARE-maskinens språkåtgärd är helt enkelt att trycka på den gamla IP, ställa in IP till en ny plats, springa tolken, och när SQUARE är klar, pop IP-adressen. (Som du kan se är IP-kvoten mot kvoten på högnivå Forth.) Detta kallas DOCOLON eller ENTER i olika Forths: Detta identiska kodfragment används av alla högnivåer (dvs. gängade) Forth definitions Thats varför en pekare till detta kodfragment, inte fragmentet i sig, ingår i förkortningsdefinitionen. Över hundratals definitioner lägger besparingarna upp och det är därför det heter Indirect threading. Kvoten från subrutinquot är ordet EXIT, som sammanställs när Forth ser. (I vissa fall kallas det S istället för EXIT.) EXIT exekverar bara en maskinspråkrutin som gör följande: Gå igenom ett par nestade Forth definitioner, för att försäkra dig om att detta fungerar. Notera egenskaperna hos ITC: varje föregående ord har ett encells kodfält. Kolondefinitioner kompilera en cell för varje ord som används i definitionen. Och den framåtriktade tolken måste faktiskt utföra en dubbel indirektion för att få adressen till nästa maskinkod att köra (först genom IP, sedan genom W). ITC är varken den minsta eller den snabbaste gängningstekniken. Det kan vara det enklaste även om DTC (beskrivet nästa) verkligen inte är mer komplex. Så varför är så många Forths indirekt-threaded För det första eftersom tidigare Forths, som används som modeller, var indirektgängade. Dessa dagar blir DTC mer populär. Så när ska ITC användas Av de olika teknikerna producerar ITC de renaste och mest eleganta definitionerna - inget annat än adresser. Om du är anpassad till sådana överväganden, kan ITC vädja till dig. Om din kod snubblar runt med insider av definitioner, kan ITC-representationens enkelhet och enhetlighet öka bärbarheten. ITC är den klassiska Forth-modellen, så det kan vara att föredra för utbildning. Slutligen, på processorer som saknar en subrutinanvisningsinstruktion - som 1802 - ITC är ofta effektivare än DTC. Direktgängad kod (DTC) Direkt trådad kod skiljer sig från ITC i endast en respekt: ​​i stället för kodfältet som innehåller adressen till någon maskinkod, innehåller kodfältet själva maskinkoden själv. Jag säger inte att den fullständiga koden för ENTER finns i varje kolondefinition I quothigh-levelquot Forth ord, innehåller kodfältet ett subrutin samtal. som visas i figur 2. Kolondefinitioner, till exempel, kommer att innehålla ett samtal till ENTER-rutinen. NÄSTA pseudokoden för direktrådning är helt enkelt: Detta ökar hastigheten: tolken utför nu bara en enda indirektion. På Z80 minskar detta NEXT-rutin - det mest använda kodfragmentet i kärnan - från elva instruktioner till sju. Det kostar utrymme: varje högnivådefinition i en Z80 Forth (till exempel) är nu en byte längre, eftersom en 2-byte-adress har ersatts av ett 3-byte-samtal. Men det här är inte helt sant. En 32-bitars 68000 Forth kan ersätta en 4-byte-adress med en 4-byte BSR-instruktion, utan förluster. Och på Zilog Super8, som har maskininstruktioner för DTC Forth, ersätts 2-byte-adressen med en 1-byte ENTER-instruktion, vilket gör en DTC Forth mindre på Super8. DTC CODE-definitionerna är naturligtvis två bitar kortare eftersom de behöver inte längre en pekare alls Jag trodde att definitioner på hög nivå i DTC Forths krävde användningen av ett subrutinanrop i kodfältet. Frank Sergeants Pygmy Forth SER90 visar att ett enkelt hopp kan användas lika enkelt och kommer vanligtvis att bli snabbare. Guy Kelly har sammanställt en fantastisk recension av Forth-implementeringar för IBM PC KEL92, som jag starkt rekommenderar till alla kärnförfattare. Av de 19 Forths studerade han, 10 använda DTC, 7 använda ITC och 2 använda subroutin threading (diskuteras därefter). Jag rekommenderar att du använder Direct-Threaded Code via Indirect-Threaded Code för alla nya Forth-kärnor. Hoppa till NEXT, eller koda den in-line Den främre inre tolken, NEXT, är en vanlig rutin för alla CODE-definitioner. Du kan bara behålla en kopia av denna vanliga rutin och få alla CODE-ord att hoppa till den. (Observera att du hoppa till NEXT ett subrutin Samtal är inte nödvändigt.) Hastigheten på NEXT är dock avgörande för hela Forth-systemet. På många processorer är NEXT-rutinen också ganska kort, ofta bara två eller tre instruktioner. Så det kan vara att föredra att koda NEXT in-line, varhelst den används. Detta görs ofta genom att göra NEXT ett assembler-makro. Detta är en enkel hastighet mot rymdbeslut: in-line NEXT är alltid snabbare, men nästan alltid större. Den totala storleken ökar är antalet extra byte som krävs för in-line expansion, gånger antalet CODE-ord i systemet. Ibland är det ingen överraskning alls: i en 6809 DTC Forth, är en in-line NEXT kortare än en Hoppa-instruktion Subroutine Threaded Code (STC) En högnivå-Forth definition är ingenting annat än en lista över subrutiner som ska utföras. Du behöver inte tolkar för att åstadkomma detta, du kan få samma effekt genom att helt enkelt stryka en lista med subrutin samtal: Se Figur 3. Denna representation av Forth ord har använts som utgångspunkt för att förklara Framåtgående tekniker för monteringstalsprogrammerare KOG82. STC är en elegant representation av kolondefinitioner och CODE-ord är nu identiska. quotDefined wordsquot (VARIABLEs, CONSTANTs och liknande) hanteras på samma sätt som i DTC - kodfältet börjar med ett hopp eller anrop till någon maskinkod någon annanstans. Den största nackdelen är att subrutin samtal är vanligtvis större än enkla adresser. På Z80, till exempel, ökar storleken på kolondefinitioner med 50 - och det mesta av din ansökan är kolondefinitioner Kontrarivis, på 32-bitars 68000 kan det inte hända att någon storlek ökar när 4-byteadresser ersätts med 4-byte BSRs. (Men om din kodstorlek överstiger 64k, måste några av dessa adresser bytas ut med 6-byte-JSR.) Subrutingängning kan vara snabbare än direktgängning. Du sparar tid genom att inte ha en tolk, men du förlorar tid eftersom varje hänvisning till ett Förhandsord innebär ett tryck och en pop av en returadress. I en DTC Forth orsakar endast högnivåord ordna aktivitet på returstapeln. På 6809 eller Zilog Super8 är DTC snabbare än STC. Det finns en annan fördel för STC: den disponerar med IP-registret. Vissa processorer - som 8051 - är desperat bristfälliga för att registrera register. Att eliminera IP kan verkligen förenkla och påskynda kärnan. Det enda sättet att veta är att skriva provkod. Detta är nära involverat i registerval, som diskuteras i nästa avsnitt. STC med direktinsamlingsoptimering för direktutbyggnad På äldre och 8-bitars processorer involverar nästan alla tidigare primitiva flera maskininstruktioner. Men på mer kraftfulla processorer skrivs många tidigare primitiva i en enda instruktion. Till exempel, på 32-bitars 68000, är ​​DROP helt enkelt I en subrutin-gängad Forth, använder DROP i en kolon definition skulle resultera i sekvensen ADDQ är en tvåbyte instruktion. Varför skriva ett subbyte för fyra byte till en tvåbyte instruktion Oavsett hur många gånger DROP används, det finns ingen sparande Koden är mindre och snabbare om ADDQ är kodad direkt i strömmen av BSR. Några Forth compilers gör denna quotin-line expansionquot av CODE ord CUR93a. Nackdelen med in-line expansion är att dekompilering tillbaka till den ursprungliga källkoden blir mycket svår. Så länge som subrutin samtal används, har du fortfarande pekare (subrutinen adresser) till Forth ord som innehåller tråden. Med pekar på orden kan du få sina namn. Men en gång har ett ord utvidgats till in-line-kod, all kunskap om var den här koden kom från är förlorad. Fördelen med in-line expansion - bortsett från hastighet och storlek - är potentialen för kodoptimering. Exempelvis skulle den föregående sekvensen sammanställas i 68000 STC som men kunde utökas in-line som en enskild maskininstruktion Optimering Forth compilers är för bred ett ämne för denna artikel. Detta är ett aktivt område för Forth språkforskning, se till exempel SCO89 och CUR93b. Den slutliga kulmineringen av optimerad STC är en Forth som kompilerar till quotpurequot maskinkod, precis som en C - eller Fortran-kompilator. Token trådad kod (TTC) DTC och STC syftar till att förbättra hastigheten på framtida program, till en viss kostnad i minnet. Nu kan vi flytta den andra riktningen från ITC, mot något långsammare men mindre. Syftet med en vidare tråd är att ange en lista över framåtordningar (subrutiner) som ska utföras. Antag att ett 16-bitars Forth-system endast hade högst 256 olika ord. Då kan varje ord identifieras unikt med ett 8-bitars nummer. Istället för en lista med 16-bitars adresser skulle du ha en lista med 8-bitars identifierare eller quottokens, cit och storleken på kolondefinitionerna skulle halveras. En token-threaded Forth håller ett bord med adresser på alla Forth ord, som visas i figur 4. Token-värdet används sedan för att indexera i den här tabellen, för att hitta framåtordet som motsvarar en given token. Detta lägger till en nivå av indirection till Forth interpreter, så det är långsammare än en quotaddress-threadedquot Forth. Den främsta fördelen med token-threaded Forths är liten storlek. TTC ses oftast i handdatorer och andra kraftigt begränsade applikationer. Dessutom kan bordet med quotentrypoints i alla Forth ord förenkla koppling av separat sammanställda moduler. Nackdelen med TTC är hastighet: TTC gör de långsammaste framåt. TTC-kompilatorn är också något mer komplex. Om du behöver mer än 256 Forth-ord behöver du ha ett öppet kodningssystem för att blanda 8-bitars och större tokens. Jag kan tänka mig en 32-bitars framåt med 16-bitars tokens, men hur många 32-bitars system är storleksbegränsad Segmentgängad kod Eftersom det finns så många 8086-derivat i världen, förtjänar segmenttråden ett kort omnämnande. I stället för att använda quotumormalquot-byteadresser inom ett 64K-segment används styckadresser. (Ett kvotvärde är 16 byte i 8086.) Då kan tolken ladda dessa adresser i segmentregistren istället för i de vanliga adressregistren. Detta gör det möjligt för en 16-bitars Forth-modell att effektivt komma åt hela megabyte 8086-minnet. Den huvudsakliga nackdelen med segmenttråden är 16-bytes quotgranularityquot av minnesutrymmet. Varje föregående ord måste anpassas till en 16-bytegräns. Om Forth ord har slumpmässiga längder, kommer ett genomsnitt på 8 byte att slösas bort per Förord. REGISTRERA ALLOVERING Vid sidan om trådertekniken är användningen av CPU-registren det viktigaste designbeslutet. Det är förmodligen det svåraste. Tillgängligheten av CPU-registren kan avgöra vilken trådläsningsteknik som kan användas, och även vad minneskartan kommer att vara Klassiska Forth-register. Den klassiska Forth-modellen har fem kvotvärda registers. quot Dessa är abstrakta enheter som används i Forths primitive operations. NEXT, ENTER och EXIT definierades tidigare med avseende på dessa abstrakta register. Var och en av dem är en cell bred - det vill säga i 16-bitars Forth är dessa 16-bitars register. (Det finns undantag från denna regel, som du kommer att se senare.) Det här är kanske inte alla CPU-register. Om din CPU inte har tillräckligt med register kan några av dessa sparas i minnet. Ill beskriver dem i storleksordning av deras betydelse, dvs botten av denna lista är de bästa kandidaterna som ska lagras i minnet. W är arbetsregistret. Den används för många saker, inklusive minnesreferens, så det borde vara ett adressregister, dvs du måste kunna hämta och lagra minne med innehållet i W som adress. Du måste också kunna göra aritmetik på W. (I DTC Forths måste du också kunna hoppa indirekt med W.) W används av tolken i varje föregående ord. I en CPU som bara har ett register, skulle du använda det för W och behålla allting i minnet (och systemet skulle vara otroligt långsamt). IP är tolkpointeren. Detta används av alla föregående ord (genom NEXT, ENTER eller EXIT). IP måste vara ett adressregister. Du måste också kunna öka IP. Subroutine threaded Forths behöver inte detta register. PSP är Parameter Stack (eller quotdata stackquot) Pointer, ibland kallas helt enkelt SP. Jag föredrar PSP eftersom SP ofta är namnet på ett CPU-register, och de borde inte vara förvirrade. De flesta CODE-ord använder det här. PSP måste vara en stapelpekare eller ett adressregister som kan ökas och minskas. Det är också ett plus om du kan göra indexerad adress från PSP. RSP är Return Stack Pointer, ibland kallas helt enkelt RP. Detta används av kolondefinitioner i ITC och DTC Forths, och av alla ord i STC Forths. RSP måste vara en stapelpekare eller ett adressregister som kan ökas och minskas. Om ens möjligt . sätt W, IP, PSP och RSP i register. De virtuella register som följer kan hållas i minnet, men det finns vanligtvis en snabb fördel att hålla dem i CPU-register. X är ett arbetsregister, inte betraktat som ett av de quotclassicalquot Forth-registeren, trots att den klassiska ITC Forths behöver det för andra indirectionen. I ITC måste du kunna hoppa indirekt med X. X kan också användas av några CODE-ord för att göra aritmetiska och så. Detta är särskilt viktigt för processorer som inte kan använda minne som operand. Till exempel kan ADD på en Z80 vara (i pseudokod) Ibland definieras även ett annat arbetsregister, Y. UP är användarpekaren och håller basadressen till arbetsområdets användarområde. UP läggs vanligtvis till förskjutning, och används av högkvalitativ Forth-kod, så det kan bara lagras någonstans. Men om CPU: n kan göra indexerad adressering från UP-registret, kan CODE-ord lättare och snabbt komma åt användarvariablerna. Om du har ett överskott av adressregistren, använd en för UP. Enkelt uppgift Förut behöver inte UPP. X - om det behövs - är viktigare att hålla sig i registret än UP. UP är det enklaste av de föregående virtuella registren att flytta till minnet. Användning av hårdvarupack De flesta processorer har en stapelpekare som en del av maskinvaran, som används av avbrott och subrutin samtal. Hur går kartan i Forth-registeren Om det är PSP eller RSP Det korta svaret beror det på. Det sägs att PSP används mer än RSP i ITC och DTC Forths. Om din CPU har få adressregistren, och PUSH och POP är snabbare än explicit referens, använd hårdvarupacken som parameterstack. Å andra sidan, om din CPU är rik på adresseringslägen - och tillåter indexerad adressering - det är ett plus att ha PSP som ett allmänt ändamålsenligt adressregister. Använd i så fall hårdvarupacken som Return Stack. Ibland gör du inte TMS320C25s hårdvarupack är bara åtta celler djupt - allt men meningslöst för Forth. Så dess hårdvarupack används endast för avbrott, och både PSP och RSP är adressbokar med allmänt ändamål. (ANS Forth anger minst 32 celler i Parameter Stack och 24 celler i Return Stack. Jag föredrar 64 celler av vardera.) Du kommer ibland att stöta på dogmen som hårdvarupacket berodde på Parameterstacken, eller kvittot tillfälle Return Stack. Istället kodar du något exempel Framför primitiver, till exempel och se vilken tillvägagångssätt som är mindre eller snabbare. (DUP och DROP är för övrigt inget test - de är vanligtvis triviala.) Ibland når du konstiga slutsatser Gary Bergstrom har påpekat att en 6809 DTC Forth kan göras några cykler snabbare genom att använda 6809 användarstapelpekaren som IP NEXT blir en POP. Han använder ett indexregister för en av Forths staplar. Top-Of-Stack in Register Framgångs prestanda kan förbättras avsevärt genom att hålla det övre elementet i Parameter Stack i ett register Många Forth ord (t. ex. 0) behöver då inte använda stacken. Andra ord gör fortfarande samma antal pushes och pops, bara på en annan plats i koden. Bara ett fåtal fortsatta ord (DROP och 2DROP) blir mer komplicerade, eftersom du inte längre kan justera stackpekaren - du måste också uppdatera TOS-registret. Det finns några regler när du skriver CODE-ord: Ett ord som tar bort objekt från stapeln måste pop-up quotnewquot-TOS i dess register. Ett ord som lägger till objekt i stapeln måste trycka quotoldquot-TOS på stapeln (såvida det inte förstås konsumeras av ordet). Om du har minst sex cellstorlek CPU-register rekommenderar jag att du håller TOS i ett register. Jag anser att TOS är viktigare än att UP ska ha register, men mindre viktigt än W, IP, PSP och RSP. (TOS i register utför många av funktionerna i X-registret.) Det är användbart om detta register kan utföra minnesadressering. PDP-11s, Z8s och 68000s är bra kandidater. Nio av de 19 IBM PC Forths som studerats av Guy Kelly KEL92 håller TOS i registret. Jag tror att den här innovationen har motsatt sig på grund av falska övertygelser om att a) det lägger till instruktioner, och b) toppstackelementet måste vara tillgängligt som minne. Det visar sig att även sådana ord som PICK, ROLL och DEPTH är trivialt modifierade för TOS-in-register. Vad sägs om att buffra två stapelelement i registren När du håller toppen av stapeln i ett register, är det totala antalet utförda åtgärder fortfarande väsentligen desamma. Ett tryck är ett tryck, oavsett om det är före eller efter den operation du utför. Å andra sidan lägger buffering av två stapelelement i registren ett stort antal instruktioner - ett tryck blir ett tryck följt av ett drag. Endast dedikerade Forth-processorer som RTX2000 och fantastiskt smart optimeringssamlare kan dra nytta av att buffra två stapelelement i registren. Några exempel Här är registeruppgifterna från Forths för ett antal olika processorer. Försök att härleda upphovsrättsdesignbesluten från den här listan. quotSPquot hänvisar till hårdvarupackpekaren. quotZpagequot refererar till värden som hålls i 6502s minnessidans noll, vilket är nästan lika användbara som - ibland mer användbara än - värden som hålls i register, t. ex. de kan användas för minnesadressering. quotFixedquot innebär att Paynes 8051 Forth har ett enda, oanvända användarområde, och UP är en hårdkodad konstant. Begränsade register Meddela någonting udda i föregående lista 6502 Forth - en 16-bitars modell - använder 8-bitars stapelpekare Det är möjligt att göra PSP, RSP och UP mindre än cellens storlek på Forth. Detta beror på att staplarna och användarområdet är båda relativt små minnesområden. Varje stapel kan vara så liten som 64 celler i längd och användarområdet överstiger sällan 128 celler. Du behöver helt enkelt se till att antingen a) dessa dataområden är begränsade till ett litet område av minne, så en kort adress kan användas, eller b) de höga adressbitarna tillhandahålls på något annat sätt, t. ex. Välj en minnessida. I 6502 begränsas hårdvarupacken till sidan en av RAM (adresserna 01xxh) av CPU: s design. 8-bitars stapelpekaren kan användas för Return Stack. Parameterstacken hålls på sidan noll av RAM, som kan indirekt nås av 8-bitars indexregistret X. (Fråga för den avancerade studenten: Varför använda 6502s X, och inte Y Tips: kolla på de tillgängliga adresseringslägena. ) I 8051 kan du använda 8-bitarsregistren R0 och R1 för att adressera externt RAM, förutsatt att du uttryckligen matar ut de höga 8 bitarna till adressen till port 2. Detta möjliggör ett kvoteringsval för två staplar. UP är annorlunda än PSP och RSP: det ger helt enkelt en basadress som aldrig ökas eller minskas. Så det är praktiskt att bara leverera de höga bitarna i detta virtuella register. De låga bitarna måste då tillhandahållas med vilken indexerad adresseringsteknik som helst. Till exempel på 6809 kan du använda DP-registret för att hålla de höga 8 bitarna av UP och sedan använda Direkt sidadressering för att komma åt någon av de 256 platserna på den här sidan. Detta tvingar alla användarområden att börja på en adress xx00h, vilket inte är något svårt och begränsar användarområdet till 128 celler i längd. På 8086 kan du tänkbart använda ett segmentregister för att ange basadressen för användarområdet. REFERENSER CUR93a Curley, Charles, quotLife i FastForth Lane, citationstecken i väntan på publicering i Forth Dimensions. Beskrivning av en 68000 subrutingängad Forth. CUR93b Curley, Charles, quotOptimizing i en BSRJSR Threaded Forth, citationstecken i väntan på publicering i Forth Dimensions. Enstaka kodoptimering för FastForth, endast i fem skärmskärmar Inkluderar notering. KEL92 Kelly, Guy M. quotForth Systems Comparisons, citationstecken Mått XIII: 6 (MarApr 1992). Också publicerad i 1991 FORML Conference Proceedings. Båda är tillgängliga från Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. Illustrerar designavvägningar från många 8086 Forths med kodfragment och referensvärden - rekommenderas KOG82 Kogge, Peter M. c. Arkitekturspår till gängade kodsystem, citerad IEEE Computer, vol. 15 nr. 3 (mar 1982). Bibehåller den slutgiltiga beskrivningen av olika gängningstekniker. ROD91 Rodriguez, B. J. quotB. Y.O. Assembler, citat Del 1, The Computer Journal 52 (SepOct 1991). Allmänna principer för skrivning Församlare. ROD92 Rodriguez, B. J. quot. B.Y. O. Assembler, citat Del 2, The Computer Journal 54 (JanFeb 1992). En 6809 assembler i Forth. SCO89 Scott, Andrew, quotAn Extensible Optimizer för kompilering framåt, citerad 1989 FORML Conference Proceedings. Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. Bra beskrivning av en 68000 optimeringsnummer utan kod. CUR86 Curley, Charles, Real-Forth för 68000. privat distribuerad (1986). JAM80 James, John S. fig-Forth för PDP-11. Forth Interest Group (1980). KUN81 Kuntze, Robert E. MVP-Forth för Apple II. Mountain View Press (1981). LAX84 Laxen, H. och Perry, M. F83 för IBM PC. version 2.1.0 (1984). Distribueras av författarna, tillgängliga från Forth Interest Group eller GEnie. LOE81 Loeliger, R. G. Gängade tolknings språk. BYTE Publications (1981), ISBN 0-07-038360-X. Kan vara den enda boken som någonsin skrivits om ämnet för att skapa en Forth-liknande kärna (det använda exemplet är Z80). Värt det om du kan hitta en kopia. MPE92 MicroProcessor Engineering Ltd. MPE Z8Super8 PowerForth-mål. MPE Ltd. 133 Hill Lane, Shirley, Southampton, S01 5AF, U. K. (June 1992). A commercial product. PAY90 Payne, William H. Embedded Controller FORTH for the 8051 Family . Academic Press (1990), ISBN 0-12-547570-5. This is a complete quotkitquot for a 8051 Forth, including a metacompiler for the IBM PC. Hardcopy only files can be downloaded from GEnie. Not for the novice SER90 Sergeant, Frank, Pygmy Forth for the IBM PC . version 1.3 (1990). Distributed by the author, available from the Forth Interest Group. Version 1.4 is now available on GEnie, and worth the extra effort to obtain. TAL80 Talbot, R. J. fig-Forth for the 6809 . Forth Interest Group (1980). Authors note for web publication: the files formerly available on the GEnie online service are now available from the Forth Interest Group FTP server, ftp:ftp. forth. orgpubForth. The Private Participation in Infrastructure (PPI) Project Database has data on over 6,400 infrastructure projects in 139 low - and middle-income countries. The database is the leading source of PPI trends in the developing world, covering projects in the energy, telecommunications, transport, and water and sewerage sectors. Some key changes were made to the methodology of the PPI database in 2015. See details here (PDF) New Sources of Financing for PPPs in 2015 Access the data on how PPPs in low and middle income countries were financed in 2015. Available under PPI Resources. - Total investments in private infrastructure in emerging markets in 2015 remained steady at US111.6 billion. - 2015 saw the largest single investment commitment ever recorded: Turkeys US35.6 billion IGA Airport. - Excluding Brazil, China, and India, global PPI in 2015 increased by 92 percent year over year. - Solar energy investment climbed 72 percent higher than the previous five-year average to reach US9.4 billion. - Renewable energy captured nearly two-thirds of energy investments with private participation. PPI in IDA Countries, 2009 to 2014: Private investment in infrastructure in IDA countries from 2009 to 2014 totaled US73 billion.

No comments:

Post a Comment