Tuesday 3 October 2017

Flytting Gjennomsnitt Implementering C


Introduksjon til ARIMA: nonseasonal modeller ARIMA (p, d, q) prognoser likning: ARIMA modeller er i teorien den mest generelle klassen av modeller for å prognose en tidsserie som kan gjøres til å være 8220stationary8221 ved differensiering (om nødvendig), kanskje i forbindelse med ikke-lineære transformasjoner som logging eller deflatering (om nødvendig). En tilfeldig variabel som er en tidsserie er stasjonær hvis dens statistiske egenskaper er konstante over tid. En stasjonær serie har ingen trend, dens variasjoner rundt sin gjennomsnitt har en konstant amplitude, og den svinger på en konsistent måte. det vil si at kortsiktige tilfeldige tidsmønstre alltid ser like ut i statistisk forstand. Den sistnevnte tilstanden betyr at dets autokorrelasjoner (korrelasjoner med sine egne tidligere avvik fra gjennomsnittet) forblir konstante over tid, eller tilsvarende, at dets effektspektrum forblir konstant over tid. En tilfeldig variabel av dette skjemaet kan ses som en kombinasjon av signal og støy, og signalet (hvis det er tydelig) kan være et mønster av rask eller saksom gjennomsnittlig reversering eller sinusformet svingning eller rask veksling i skiltet , og det kan også ha en sesongbestemt komponent. En ARIMA-modell kan ses som en 8220filter8221 som forsøker å skille signalet fra støyen, og signalet blir deretter ekstrapolert inn i fremtiden for å oppnå prognoser. ARIMA-prognose-ligningen for en stasjonær tidsserie er en lineær (dvs. regresjonstype) ekvation hvor prediktorene består av lag av de avhengige variable ogor lagene av prognosefeilene. Det er: Forutsigbar verdi for Y en konstant og en vektet sum av en eller flere nylige verdier av Y og eller en vektet sum av en eller flere nylige verdier av feilene. Hvis prediktorene kun består av forsinkede verdier av Y. Det er en ren autoregressiv (8220self-regressed8221) modell, som bare er et spesielt tilfelle av en regresjonsmodell, og som kunne være utstyrt med standard regresjonsprogramvare. For eksempel er en førsteordens autoregressiv (8220AR (1) 8221) modell for Y en enkel regresjonsmodell der den uavhengige variabelen bare er Y forsinket med en periode (LAG (Y, 1) i Statgraphics eller YLAG1 i RegressIt). Hvis noen av prediktorene er lags av feilene, er en ARIMA-modell det IKKE en lineær regresjonsmodell, fordi det ikke er mulig å spesifisere 8220last period8217s error8221 som en uavhengig variabel: feilene må beregnes fra tid til annen når modellen er montert på dataene. Fra et teknisk synspunkt er problemet med å bruke forsinkede feil som prediktorer at modellen8217s spådommer ikke er lineære funksjoner av koeffisientene. selv om de er lineære funksjoner av tidligere data. Så koeffisienter i ARIMA-modeller som inkluderer forsinkede feil må estimeres ved ikke-lineære optimaliseringsmetoder (8220hill-klatring8221) i stedet for bare å løse et system av ligninger. Akronymet ARIMA står for Auto-Regressive Integrated Moving Average. Lags av den stationære serien i prognosekvotasjonen kalles kvotoregressivequot-termer. Lags av prognosefeilene kalles quotmoving averagequot vilkår, og en tidsserie som må differensieres for å bli stillestående, sies å være en quotintegratedquot-versjon av en stasjonær serie. Tilfeldige gange og tilfeldige trendmodeller, autoregressive modeller og eksponentielle utjevningsmodeller er alle spesielle tilfeller av ARIMA-modeller. En nonseasonal ARIMA-modell er klassifisert som en quotARIMA (p, d, q) kvotemodell hvor: p er antall autoregressive termer, d er antall ikke-sekundære forskjeller som trengs for stasjonar, og q er antall forsinkede prognosefeil i prediksjonsligningen. Forutsigelsesligningen er konstruert som følger. Først, la y betegne den d forskjellen på Y. Det betyr: Merk at den andre forskjellen på Y (d2-saken) ikke er forskjellen fra 2 perioder siden. Snarere er det den første forskjellen-av-første forskjellen. som er den diskrete analogen til et andre derivat, det vil si den lokale akselerasjonen av serien i stedet for sin lokale trend. Når det gjelder y. Den generelle prognosekvasjonen er: Her er de bevegelige gjennomsnittsparametrene (9528217s) definert slik at deres tegn er negative i ligningen, etter konvensjonen innført av Box og Jenkins. Noen forfattere og programvare (inkludert R programmeringsspråket) definerer dem slik at de har pluss tegn i stedet. Når faktiske tall er koblet til ligningen, er det ingen tvetydighet, men det er viktig å vite hvilken konvensjon programvaren bruker når du leser utgangen. Ofte er parametrene benevnt der av AR (1), AR (2), 8230 og MA (1), MA (2), 8230 etc. For å identifisere den aktuelle ARIMA modellen for Y. begynner du ved å bestemme differensordren (d) trenger å stasjonærisere serien og fjerne bruttoegenskapene til sesongmessighet, kanskje i forbindelse med en variansstabiliserende transformasjon som logging eller deflating. Hvis du stopper på dette punktet og forutsier at den forskjellige serien er konstant, har du bare montert en tilfeldig tur eller tilfeldig trendmodell. Den stasjonære serien kan imidlertid fortsatt ha autokorrelerte feil, noe som tyder på at noen antall AR-termer (p 8805 1) og eller noen nummer MA-termer (q 8805 1) også er nødvendig i prognosekvasjonen. Prosessen med å bestemme verdiene p, d og q som er best for en gitt tidsserie, vil bli diskutert i senere avsnitt av notatene (hvis koblinger er øverst på denne siden), men en forhåndsvisning av noen av typene av nonseasonal ARIMA-modeller som ofte oppstår, er gitt nedenfor. ARIMA (1,0,0) førstegangs autoregressiv modell: Hvis serien er stasjonær og autokorrelert, kan den kanskje forutsies som et flertall av sin egen tidligere verdi, pluss en konstant. Forutsigelsesligningen i dette tilfellet er 8230 som er Y regressert i seg selv forsinket med en periode. Dette er en 8220ARIMA (1,0,0) constant8221 modell. Hvis gjennomsnittet av Y er null, vil ikke det konstante begrepet bli inkludert. Hvis hellingskoeffisienten 981 1 er positiv og mindre enn 1 i størrelsesorden (den må være mindre enn 1 i størrelsesorden dersom Y er stasjonær), beskriver modellen gjennomsnittsreferanseadferd hvor neste periode8217s verdi skal anslås å være 981 1 ganger som langt unna gjennomsnittet som denne perioden8217s verdi. Hvis 981 1 er negativ, forutser det middelreferanseadferd med skifting av tegn, dvs. det forutsier også at Y vil være under gjennomsnittlig neste periode hvis den er over gjennomsnittet denne perioden. I en andre-ordregivende autoregressiv modell (ARIMA (2,0,0)), ville det være et Y t-2 begrep til høyre også, og så videre. Avhengig av tegnene og størrelsene på koeffisientene, kunne en ARIMA (2,0,0) modell beskrive et system hvis gjennomsnitts reversering foregår i sinusformet oscillerende mote, som bevegelse av en masse på en fjær som er utsatt for tilfeldige støt . ARIMA (0,1,0) tilfeldig tur: Hvis serien Y ikke er stasjonær, er den enkleste modellen for den en tilfeldig turmodell, som kan betraktes som et begrensende tilfelle av en AR (1) modell der autoregressive koeffisienten er lik 1, det vil si en serie med uendelig sakte gjennomsnittlig reversering. Forutsigelsesligningen for denne modellen kan skrives som: hvor den konstante sikt er den gjennomsnittlige perioden til periode-endringen (dvs. den langsiktige driften) i Y. Denne modellen kan monteres som en ikke-avskjæringsregresjonsmodell der Første forskjell på Y er den avhengige variabelen. Siden den inneholder (bare) en ikke-soneforskjell og en konstant periode, er den klassifisert som en quotARIMA (0,1,0) modell med constant. quot. Den tilfeldig-walk-uten-drift-modellen ville være en ARIMA (0,1, 0) modell uten konstant ARIMA (1,1,0) forskjellig førsteordens autoregressiv modell: Hvis feilene i en tilfeldig turmodell er autokorrelert, kan problemet løses ved å legge til et lag av den avhengige variabelen til prediksjonsligningen - - dvs ved å regresse den første forskjellen på Y i seg selv forsinket med en periode. Dette vil gi følgende prediksjonsligning: som kan omarrangeres til Dette er en førsteordens autoregressiv modell med en rekkefølge av ikke-soneforskjeller og en konstant term, dvs. en ARIMA (1,1,0) modell. ARIMA (0,1,1) uten konstant enkel eksponensiell utjevning: En annen strategi for korrigering av autokorrelerte feil i en tilfeldig gangmodell er foreslått av den enkle eksponensielle utjevningsmodellen. Husk at for noen ikke-stationære tidsserier (for eksempel de som viser støyende svingninger rundt et sakte varierende gjennomsnitt), utfører ikke den tilfeldige turmodellen så vel som et glidende gjennomsnittsverdier av tidligere verdier. Med andre ord, i stedet for å ta den nyeste observasjonen som prognosen for neste observasjon, er det bedre å bruke et gjennomsnitt av de siste observasjonene for å filtrere ut støy og mer nøyaktig anslå det lokale gjennomsnittet. Den enkle eksponensielle utjevningsmodellen bruker et eksponentielt vektet glidende gjennomsnitt av tidligere verdier for å oppnå denne effekten. Forutsigelsesligningen for den enkle eksponensielle utjevningsmodellen kan skrives i en rekke matematisk ekvivalente former. hvorav den ene er den såkalte 8220error correction8221 skjemaet, der den forrige prognosen er justert i retning av feilen det gjorde: Fordi e t-1 Y t-1 - 374 t-1 per definisjon kan dette omskrives som : som er en ARIMA (0,1,1) - out-konstant prognosekvasjon med 952 1 1 - 945. Dette betyr at du kan passe en enkel eksponensiell utjevning ved å angi den som en ARIMA (0,1,1) modell uten konstant, og den estimerte MA (1) - koeffisienten tilsvarer 1-minus-alfa i SES-formelen. Husk at i SES-modellen er gjennomsnittsalderen for dataene i 1-periode fremover prognosene 1 945. Det betyr at de vil ha en tendens til å ligge bak trender eller vendepunkter med ca 1 945 perioder. Det følger at gjennomsnittlig alder av dataene i 1-periode fremover prognosene for en ARIMA (0,1,1) uten konstant modell er 1 (1 - 952 1). For eksempel, hvis 952 1 0,8 er gjennomsnittsalderen 5. Når 952 1 nærmer seg 1, blir ARIMA (0,1,1) uten konstant modell et veldig langsiktig glidende gjennomsnitt og som 952 1 nærmer seg 0 blir det en tilfeldig tur uten drivmodell. What8217s den beste måten å korrigere for autokorrelasjon: legge til AR-vilkår eller legge til MA-vilkår I de to foregående modellene ble problemet med autokorrelerte feil i en tilfeldig turmodell løst på to forskjellige måter: ved å legge til en forsinket verdi av differensierte serier til ligningen eller legge til en forsinket verdi av prognosen feil. Hvilken tilnærming er best En tommelfingerregel for denne situasjonen, som vil bli nærmere omtalt senere, er at positiv autokorrelasjon vanligvis behandles best ved å legge til et AR-uttrykk for modellen og negativ autokorrelasjon vanligvis behandles best ved å legge til en MA term. I forretnings - og økonomiske tidsserier oppstår negativ autokorrelasjon ofte som en artefakt av differensiering. (Generelt reduserer differensiering positiv autokorrelasjon og kan til og med føre til en bryter fra positiv til negativ autokorrelasjon.) Så, ARIMA (0,1,1) modellen, der differensiering er ledsaget av en MA-term, brukes hyppigere enn en ARIMA (1,1,0) modell. ARIMA (0,1,1) med konstant enkel eksponensiell utjevning med vekst: Ved å implementere SES-modellen som en ARIMA-modell, får du faktisk en viss fleksibilitet. Først og fremst er estimert MA (1) - koeffisient tillatt å være negativ. Dette tilsvarer en utjevningsfaktor som er større enn 1 i en SES-modell, som vanligvis ikke er tillatt i SES-modellprosedyren. For det andre har du muligheten til å inkludere en konstant periode i ARIMA-modellen hvis du ønsker det, for å estimere en gjennomsnittlig ikke-null trend. ARIMA-modellen (0,1,1) med konstant har prediksjonsligningen: Forventningene for en periode fremover fra denne modellen er kvalitativt lik SES-modellen, bortsett fra at bane av de langsiktige prognosene vanligvis er en skrånende linje (hvis skråning er lik mu) i stedet for en horisontal linje. ARIMA (0,2,1) eller (0,2,2) uten konstant lineær eksponensiell utjevning: Linjære eksponentielle utjevningsmodeller er ARIMA-modeller som bruker to ikke-soneforskjeller i sammenheng med MA-termer. Den andre forskjellen i en serie Y er ikke bare forskjellen mellom Y og seg selv forsinket av to perioder, men det er den første forskjellen i den første forskjellen - dvs. Y-endringen i Y i periode t. Således er den andre forskjellen på Y ved periode t lik (Y t - Y t-1) - (Y t-1 - Y t-2) Y t - 2Y t-1 Y t-2. En annen forskjell på en diskret funksjon er analog med et andre derivat av en kontinuerlig funksjon: den måler kvoteringsberegningsquot eller kvoturvitaquot i funksjonen på et gitt tidspunkt. ARIMA-modellen (0,2,2) uten konstant forutser at den andre forskjellen i serien er lik en lineær funksjon av de to siste prognosefeilene: som kan omarrangeres som: hvor 952 1 og 952 2 er MA (1) og MA (2) koeffisienter. Dette er en generell lineær eksponensiell utjevningsmodell. i hovedsak det samme som Holt8217s modell, og Brown8217s modell er et spesielt tilfelle. Den bruker eksponensielt vektede glidende gjennomsnitt for å anslå både et lokalt nivå og en lokal trend i serien. De langsiktige prognosene fra denne modellen konvergerer til en rett linje hvis skråning avhenger av den gjennomsnittlige trenden observert mot slutten av serien. ARIMA (1,1,2) uten konstant fuktet trend lineær eksponensiell utjevning. Denne modellen er illustrert i de tilhørende lysbildene på ARIMA-modellene. Den ekstrapolerer den lokale trenden i slutten av serien, men flater ut på lengre prognoshorisonter for å introdusere et konservatismedokument, en praksis som har empirisk støtte. Se artikkelen om hvorfor Damped Trend worksquot av Gardner og McKenzie og quotgolden Rulequot-artikkelen av Armstrong et al. for detaljer. Det er generelt tilrådelig å holde fast i modeller der minst en av p og q ikke er større enn 1, dvs. ikke prøv å passe på en modell som ARIMA (2,1,2), da dette sannsynligvis vil føre til overfitting og kvadrat-faktorquot problemer som er omtalt nærmere i notatene om den matematiske strukturen til ARIMA-modellene. Implementering av regneark: ARIMA-modeller som de som er beskrevet ovenfor, er enkle å implementere på et regneark. Forutsigelsesligningen er bare en lineær ligning som refererer til tidligere verdier av originale tidsserier og tidligere verdier av feilene. Dermed kan du sette opp et ARIMA prognose regneark ved å lagre dataene i kolonne A, prognoseformelen i kolonne B, og feilene (data minus prognoser) i kolonne C. Forutsigelsesformelen i en typisk celle i kolonne B ville ganske enkelt være et lineært uttrykk som refererer til verdier i forrige rader med kolonne A og C, multiplisert med de relevante AR - eller MA-koeffisientene lagret i celler andre steder på regnearket. MOVING FORTH Del 1: Designbeslutninger i fremre kjernen av Brad Rodriguez Denne artikkelen ble først oppført i The Computer Journal 59 (januar februar 1993). INNLEDNING Alle i Forth samfunn snakker om hvor lett det er å porten Forth til en ny CPU. Men som mange quoteasyquot - og quotobviousquot-oppgaver, er det ikke skrevet mye om hvordan å gjøre det. Så, da Bill Kibler foreslo dette emnet for en artikkel, bestemte jeg meg for å bryte med den store muntlige tradisjonen til Forthwrights, og dokumentere prosessen i svart og hvitt. I løpet av disse artiklene vil jeg utvikle Forths for 6809, 8051 og Z80. Jeg gjør 6809 for å illustrere en enkel og konvensjonell Forth-modell pluss, Ive har allerede publisert en 6809 assembler ROD91, ROD92, og jeg trenger en 6809 Forth for fremtidige TCJ-prosjekter. Jeg gjør 8051 Forth for et universitetsprosjekt, men det illustrerer også noen ganske forskjellige designbeslutninger. Z80 Forth er for alle CPM-leserne til TCJ, og for noen venner med TRS-80s som samler støv. ESSENTIAL HARDWARE Du må velge en CPU. Jeg vil ikke dykke inn i fordelene til en CPU over en annen for Forth, siden en CPU-valg vanligvis blir tvunget på deg av andre hensyn. Dessuten er gjenstanden for denne artikkelen å vise hvordan man beveger seg frem til hvilken som helst CPU. Du kan forvente den vanlige 16-biters fremre kjernen (se nedenfor) for å oppta omtrent 8K byte av programplass. For en full kjerne som kan kompilere Forth-definisjoner, bør du tillate minst 1 K byte RAM. For å bruke Forhånds blokkeringssystem for diskoppbevaring, bør du legge til 3 Kbytes eller mer for buffere. For en 32-biters Forth-modell, doble disse tallene. Dette er minimumene for å få en kjerne fremover. Hvis du vil kjøre et program på maskinvaren din, bør du øke PROM og RAM-størrelsen som passer. 16 ELLER 32 BIT Ordstørrelsen som brukes av Forth, er ikke nødvendigvis den samme som for CPU. Den minste praktiske Forth er en 16-biters modell, dvs. en som bruker 16-biters heltall og 16-biters adresser. Det fremre samfunnet kaller dette kvotcellquot-størrelsen, siden quotwordquot refererer til en videre definisjon. 8-bits CPUer støtter nesten alltid 16-biters fremover. Dette krever vanligvis eksplisitt koding av dobbeltbyte-aritmetikk, selv om noen 8-biters CPUer har noen 16-biters operasjoner. 16-biters CPUer kjører vanligvis 16-biters fremover, selv om de samme dobbelte presisjonsteknikkene kan brukes til å skrive en 32-biters fremover på en 16-biters CPU. Minst en 32-biters Forth har blitt skrevet for 80868088. 32-bits CPUer kjører normalt 32-biters Forths. En mindre Forth-modell sparer sjelden kodenes lengde eller prosessortiden. Imidlertid vet jeg om minst en 16-bit Forth skrevet for 68000. Dette krymper programkodestørrelsen med en faktor på to, siden høydefinisjoner Forth definisjoner blir en streng med 16-biters adresser i stedet for en streng på 32- bit adresser. (Dette kommer snart til syne.) De fleste 68000-er har nok RAM. Alle eksemplene som er beskrevet i denne artikkelen, er 16-biters fremover som kjører på 8-bits CPUer. THREADING TECHNIQUE quotedread codequot er kjennetegnet for Forth. En videre quotthreadquot er bare en liste over adresser til rutiner som skal utføres. Du kan tenke på dette som en liste over subrutineanrop, med CALL-instruksjonene fjernet. Gjennom årene har mange trekkvariasjoner blitt utarbeidet, og hvilken som er best avhenger av CPU og applikasjonen. For å ta en avgjørelse må du forstå hvordan de fungerer, og deres avvik. Indirekte trådkode (ITC) Dette er den klassiske Forth-trekkteknikken, brukt i fig. Forth og F83, og beskrevet i de fleste bøkene på Forth. Alle de andre threading ordninger er quotimprovementsquot på dette, så du må forstå ITC å sette pris på de andre. La oss se på definisjonen av et forutgående ord SQUARE: I en typisk ITC Forth vil dette vises i minnet som vist i Figur 1. (Overskriften vil bli diskutert i en fremtidig artikkel, den inneholder housekeeping-informasjon som brukes til kompilering, og er ikke involvert i tråder .) Anta at SQUARE oppstår mens du utfører et annet fremtidsord. Forward Interpreter Pointer (IP) vil peke til en celle i minnet - som er inneholdt i det kvoterende ordet - som inneholder adressen til ordet SQUARE. (For å være presis, inneholder cellen en adresse til SQUAREs Code Field.) Tolken henter den adressen, og bruker den til å hente innholdet i SQUAREs Code Field. Disse innholdene er enda en adresse - adressen til en maskinsprogsunderrutine som utfører ordet SQUARE. I pseudokode er dette: Dette illustrerer et viktig, men sjelden uttalt prinsipp: Adressen til det fremre ordet som nettopp er skrevet inn, holdes i W. CODE-ord, trenger ikke denne informasjonen, men alle andre typer fremtredende ord gjør det. Hvis SQUARE ble skrevet i maskinskode, ville dette være slutten på historien: den lille maskinkoden ville bli utført, og deretter hoppe tilbake til Fortholken - som, siden IP ble økt, peker på neste ord til utføres. Det er derfor den fremre tolken vanligvis kalles NESTE. Men, SQUARE er et høyt nivå kvotekvot definisjon - den inneholder en quotthreadquot, en liste over adresser. For å utføre denne definisjonen, må Forth-tolken bli startet på nytt på et nytt sted: Parameterfeltet for SQUARE. Selvfølgelig må tolkernes gamle plassering bli lagret, for å gjenoppta kvoterkvoten Fortsatt ord når SQUARE er ferdig. Dette er akkurat som en subrutine-anrop Maskinens språkhandling av SQUARE er ganske enkelt å trykke den gamle IP-en, sette IP til et nytt sted, kjøre tolken, og når SQUARE er ferdig, trykk IP. (Som du ser, er IP-kvoten mot kvoten på høyt nivå Forth.) Dette kalles DOCOLON eller ENTER i ulike Forths: Dette identiske kodefragmentet brukes av alle høyt nivåer (dvs. gjenget) Forth definitions Thats hvorfor en peker til dette kodefragmentet, ikke selve fragmentet, er inkludert i den forrige definisjonen. Over hundrevis av definisjoner, legger besparelsene opp Og dette er grunnen til at det kalles Indirekte tråder. Kvoturnetten fra subroutinequot er ordet EXIT, som blir kompilert når Forth ser. (Noen fremover kaller det S i stedet for EXIT.) EXIT utfører bare en maskinsprogrutine som gjør følgende: Gå gjennom et par nestede Forth definisjoner, for å forsikre deg selv om at dette fungerer. Legg merke til egenskapene til ITC: hvert fremre ord har et en-celle kodefelt. Kolondefinisjoner kompilere en celle for hvert ord som brukes i definisjonen. Og den fremre tolken må faktisk utføre en dobbelt indireksjon for å få adressen til den neste maskinkoden å løpe (først gjennom IP, deretter gjennom W). ITC er hverken den minste eller den raskeste gjengeteknikken. Det kan være den enkleste, selv om DTC (beskrevet neste) egentlig ikke er mer komplisert. Så hvorfor er så mange Forths indirekte-threaded Hovedsakelig fordi tidligere Forths, brukt som modeller, var indirekte-threaded. I disse dager blir DTC blitt mer populært. Så når skal ITC bli brukt Av de ulike teknikkene produserer ITC de reneste og mest elegante definisjonene - ingenting annet enn adresser. Hvis du er avhengig av slike hensyn, kan ITC appellere til deg. Hvis koden fins rundt med innsiden av definisjonene, kan enkelheten og ensartetheten av ITC-representasjonen øke overførbarheten. ITC er den klassiske Forth-modellen, så det kan være foretrukket for utdanning. Til slutt, på CPUer som mangler en subrutine-anropsinstruksjon - for eksempel 1802 - ITC er ofte mer effektiv enn DTC. Direct Threaded Code (DTC) Direct Threaded Code er forskjellig fra ITC i bare én respekt: ​​i stedet for kodefeltet som inneholder adressen til en maskinkode, inneholder kodefeltet selve maskinskoden selv. Jeg sier ikke at den komplette koden for ENTER er inneholdt i hver kolondefinisjon I quothigh-levelquot Frem ord, vil kodefeltet inneholde et subrutineanrop. som vist i figur 2. Kolondefinisjoner, for eksempel, vil inneholde et anrop til ENTER-rutinen. NESTE pseudo-koden for direkte tråder er rett og slett: Dette gir hastighet: tolken utfører nå bare en enkelt indireksjon. På Z80 reduserer dette NEXT-rutinen - det mest brukte kodefragmentet i den fremre kjernen - fra elleve instruksjoner til syv. Dette koster plass: hver høydefinisjonsdefinisjon i en Z80 Forth (for eksempel) er nå en byte lenger, siden en 2-byte-adresse er erstattet av et 3-byte-anrop. Men dette er ikke helt sant. En 32-bit 68000 Forth kan erstatte en 4-byte-adresse med en 4-byte BSR-instruksjon, uten tap av nett. Og på Zilog Super8, som har maskininstruksjoner for DTC Forth, erstattes 2-byte-adressen med en 1-byte ENTER-instruksjon, noe som gjør DTC Forth mindre på Super8 Selvfølgelig er DTC CODE-definisjonene to byte kortere, siden de Jeg trengte ikke lenger en pointer. Jeg pleide å tro at definisjoner på høyt nivå i DTC Forths krevde bruk av et subrutineanrop i kodefeltet. Frank Sergeants Pygmy Forth SER90 demonstrerer at et enkelt hopp kan brukes like enkelt, og vil vanligvis være raskere. Guy Kelly har samlet en flott gjennomgang av Forth-implementeringer for IBM PC KEL92, som jeg sterkt anbefaler til alle kjerneforfattere. Av 19 Forths studerte han, brukte 10 DTC, 7 brukte ITC og 2 brukte subrutine-tråder (diskuteres neste). Jeg anbefaler bruk av Direct-Threaded Code over Indirect-Threaded Code for alle nye Forth-kjerner. Hopp til NEXT, eller kodes det in-line Den fremre indre tolk, NEXT, er en felles rutine for alle CODE-definisjoner. Du kan bare beholde en kopi av denne vanlige rutinen, og få alle CODE-ordene til å hoppe over det. (Merk at du hopper til NEXT en subrutine Ring er ikke nødvendig.) Hastigheten til NEXT er imidlertid avgjørende for hastigheten til hele Forth-systemet. Også på mange CPUer er NEXT-rutinen ganske kort, ofte bare to eller tre instruksjoner. Så det kan være å foretrekke å kode NEXT in-line, uansett hvor det er brukt. Dette gjøres ofte ved å lage NEXT en assembler-makro. Dette er en enkel hastighet versus plassbeslutning: in-line NEXT er alltid raskere, men nesten alltid større. Den totale størrelsesøkningen er antall ekstra byte som kreves for utvidelse i linje, ganger antall CODE-ord i systemet. Noen ganger er det ingen bytte i det hele tatt: i en 6809 DTC Forth, er en in-line NEXT kortere enn en Jump Instruction Subroutine Threaded Code (STC). En høydefinisjon på forhånd er ingenting annet enn en liste over underrutiner som skal utføres. Du trenger ikke tolker for å oppnå dette, men du kan få samme effekt ved å bare stryke en liste over subrutine samtaler sammen: Se figur 3. Denne representasjonen av Forth-ord har blitt brukt som utgangspunkt for å forklare Forth threading teknikker til montering språk programmerere KOG82. STC er en elegant representasjon kolon definisjoner og CODE ord er nå identiske. quotDefined wordsquot (VARIABLEs, CONSTANTs og lignende) håndteres på samme måte som i DTC - kodefeltet begynner med et hopp eller ring til noen maskinkode andre steder. Den største ulempen er at subrutineanrop vanligvis er større enn enkle adresser. På Z80, for eksempel, øker størrelsen på kolondefinisjonene med 50 - og det meste av søknaden er kolondefinisjoner Kontrarivis, på 32-biters 68000 kan det ikke være noen størrelsesøkning i det hele tatt når 4-byte-adresser erstattes med 4-byte BSRer. (Men hvis kodestørrelsen overskrider 64K, må noen av disse adressene byttes ut med 6-bytes JSR.) Subroutine-tråden kan være raskere enn direkte tråder. Du sparer tid ved ikke å ha tolk, men du mister tid fordi alle henvisninger til et fremtidsord innebærer en trykk og pop på en returadresse. I en DTC Forth, forårsaker kun høyt nivå ord på aktivitet på returbunken. På 6809 eller Zilog Super8 er DTC raskere enn STC. Det er en annen fordel for STC: den dispenserer med IP-registeret. Noen prosessorer - som 8051 - er desperat kort for å adressere registre. Å eliminere IP kan virkelig forenkle og øke hastigheten på kjernen. Den eneste måten å vite, er å skrive eksempelkode. Dette er nært involvert med registervalg, diskutert i neste avsnitt. STC med direkte ekspansjonsoptimalisering på eldre og 8-bits CPUer, omfatter nesten alle tidligere primitive flere maskininstruksjoner. Men på mer kraftige CPUer, er mange tidligere primitiver skrevet i en enkelt instruksjon. For eksempel på 32-bit 68000 er DROP ganske enkelt I en subrutin-threaded Forth, ved å bruke DROP i et kolon definisjon vil resultere i sekvensen ADDQ er en tobyte instruksjon. Hvorfor skrive en firebyte-subrutineanrop til en tobyte-instruksjon Uansett hvor mange ganger DROP er brukt, er det ingen besparelser Koden er mindre og raskere hvis ADDQ er kodet direkte inn i strømmen av BSRer. Noen fremtredende kompilatorer gjør dette kvote-line expansionskvoten av CODE-ordene CUR93a. Ulempen med in-line ekspansjon er at dekompilering tilbake til den opprinnelige kildekoden blir svært vanskelig. Så lenge subroutine-anrop brukes, har du fremdeles pekere (subrutinadressene) til de fremre ordene som omfatter tråden. Med pekere til ordene, kan du få navnene sine. Men når et ord er utvidet til in-line-kode, er all kunnskap om hvor den koden kommer fra, tapt. Fordelen med in-line ekspansjon - bortsett fra hastighet og størrelse - er potensialet for kodeoptimalisering. For eksempel vil Forth-sekvensen bli kompilert i 68000 STC som, men kunne utvides i tråd som en enkelt maskininstruksjon. Optimering Forth compilers er for bredt et emne for denne artikkelen. Dette er et aktivt område av Forth språkforskning se for eksempel SCO89 og CUR93b. Den endelige kulminasjonen av optimalisert STC er en Forth som kompilerer til quotpurequot maskinkode, akkurat som en C - eller Fortran-kompilator. Token trådkode (TTC) DTC og STC tar sikte på å forbedre hastigheten på fremtidige programmer, til en viss pris i minnet. Nå kan vi flytte den andre retningen fra ITC, mot noe langsommere men mindre. Formålet med en videre tråd er å spesifisere en liste over fremtredende ord (subrutiner) som skal utføres. Anta at et 16-biters Forth-system bare hadde maksimalt 256 forskjellige ord. Deretter kunne hvert ord unikt identifiseres med et 8-biters tall. I stedet for en liste over 16-biters adresser, vil du ha en liste over 8-biters identifikatorer eller quottokens, og kvadratstørrelsenes definisjoner vil bli halvert. En token-threaded Forth beholder en tabell med adresser på alle fremtredende ord, som vist i figur 4. Tollverdien brukes deretter til å indeksere i denne tabellen for å finne fremre ord som svarer til et gitt token. Dette legger til et nivå av indireksjon til den fremre tolken, så det er tregere enn en kvadratkryss-threadedquot Forth. Hovedfordelen ved token-threaded Forths er liten størrelse. TTC er mest sett i håndholdte datamaskiner og andre alvorlige størrelsesbegrensede applikasjoner. Dessuten kan tabellen med quotentrypoints i alle Forth-ordene forenkle sammenkobling av separatutviklede moduler. Ulempen med TTC er hastighet: TTC gjør den tregeste fremtiden. TTC-kompilatoren er også litt mer kompleks. Hvis du trenger mer enn 256 Forth-ord, er det nødvendig å ha en åpen kodingsordning for å blande 8-biters og større tokens. Jeg kan forestille en 32-biters Forth ved hjelp av 16-biters tokens, men hvor mange 32-biters systemer er størrelsesbegrenset Segment Threaded Code Siden det er så mange 8086-derivater i verden, fortjener segmenttråden en kort omtale. I stedet for å bruke quotumormalquot byte-adresser i et 64K-segment, brukes avsnittadresser. (En kvotestilling er 16 byte i 8086.) Så kan tolken laste disse adressene inn i segmentregistre, i stedet for å inn i de vanlige adressene. Dette tillater en 16-biters Forth-modell for effektivt å få tilgang til hele megabyte 8086-minnet. Den viktigste ulempen ved segmenttråden er 16-byte kvadratkvotalitetskvoten i minnet. Hvert fremre ord må være justert til en 16-byte grense. Hvis Forth ord har tilfeldige lengder, vil et gjennomsnitt på 8 byte bli bortkastet per Forth ord. REGISTRERING AV TILDELING Ved siden av gjengeteknikken er bruk av CPU-registre den mest avgjørende designbeslutningen. Det er sannsynligvis det vanskeligste. Tilgjengeligheten av CPU-registre kan avgjøre hvilken trådeteknikk som kan brukes, og til og med hva minnekortet vil være De klassiske fremkallingsregistrene Den klassiske Forth-modellen har fem kvotetiske registers. quot Disse er abstrakte enheter som brukes i primitive operasjoner av Forth. NEXT, ENTER og EXIT ble tidligere definert i form av disse abstrakte registre. Hver av disse er en cellevidde - det vil si i 16-biters Forth, disse er 16-biters register. (Det er unntak fra denne regelen, som du vil se senere.) Disse er kanskje ikke alle CPU-registre. Hvis CPUen ikke har nok register, kan noen av disse lagres i minnet. Jeg beskriver dem i rekkefølgen av deres betydning, dvs. bunnen av denne listen er de beste kandidatene som skal lagres i minnet. W er arbeidsregisteret. Den brukes til mange ting, inkludert minne referanse, så det skal være et adresseregister, dvs. du må kunne hente og lagre minne ved hjelp av innholdet i W som adresse. Du må også kunne gjøre aritmetikk på W. (I DTC Forths må du også kunne hoppe indirekte ved hjelp av W.) W brukes av tolken i hvert forutgående ord. I en CPU som bare har ett register, vil du bruke det til W og beholde alt annet i minnet (og systemet vil være utrolig sakte). IP er tolkpointeren. Dette brukes av hvert forkortet ord (gjennom NEXT, ENTER eller EXIT). IP må være et adresseregister. Du må også kunne øke IP. Subroutine threaded Forths trenger ikke dette registret. PSP er Parameter Stack (eller quotdata stackquot) Pointer, noen ganger kalt bare SP. Jeg foretrekker PSP fordi SP ofte er navnet på et CPU-register, og de bør ikke forveksles. De fleste CODE-ord bruker dette. PSP må være en stabelpeker eller et adresseregister som kan økes og dekrementeres. Det er også et pluss hvis du kan gjøre indeksert adressering fra PSP. RSP er Return Stack Pointer, noen ganger kalt bare RP. Dette brukes av kolondefinisjoner i ITC og DTC Forths, og av alle ord i STC Forths. RSP må være en stabelpeker, eller et adresseregister som kan økes og dekrementeres. Hvis i det hele tatt mulig. sett W, IP, PSP, og RSP i registre. De virtuelle registre som følger kan holdes i minnet, men det er vanligvis en rask fordel å holde dem i CPU-registre. X er et arbeidsregister, ikke betraktet som et av kvoteklassifiseringen Forth-register, selv om den klassiske ITC Forths trenger det for den andre indireksjonen. I ITC må du kunne hoppe indirekte ved hjelp av X. X kan også brukes av noen CODE-ord for å gjøre aritmetiske og lignende. Dette er spesielt viktig på prosessorer som ikke kan bruke minne som operand. For eksempel kan ADD på en Z80 være (i pseudokode) Noen ganger er et annet arbeidsregister, Y, også definert. UP er brukerpekeren, og holder basen til oppgavens brukerområde. UP er vanligvis lagt til en forskyvning, og brukes av høyt nivå fremkodskode, så det kan bare lagres et sted. Men hvis CPUen kan gjøre indeksert adressering fra UP-registeret, kan CODE-ordene lettere og raskt få tilgang til brukervariabler. Hvis du har et overskudd av adresseregister, bruk en for UP. Enkeltoppgave fremover trenger ikke opp. X - om nødvendig - er viktigere å være i register enn UP. UP er det enkleste av de fremre virtuelle registre for å flytte inn i minnet. Bruk av maskinvarestabletten De fleste CPUer har en stabelpeker som en del av maskinvaren, som brukes av interrupts og subroutine-samtaler. Hvordan går dette kartet inn i Forth-registerene Skulle det være PSP eller RSP Det korte svaret er, det avhenger. Det sies at PSP brukes mer enn RSP i ITC og DTC Forths. Hvis CPUen har få adresseregister, og PUSH og POP er raskere enn eksplisitt referanse, bruker du maskinvarebunken som Parameter Stack. På den annen side, hvis CPUen er rik på adressemoduser - og tillater indeksert adressering - er det et pluss å ha PSP som et generelt adresseliste. I dette tilfellet bruker du maskinvarebunken som Return Stack. Noen ganger gjør du heller ikke TMS320C25s maskinvarebunke er bare åtte celler dyp - alt annet enn ubrukelig for Forth. Derfor er maskinvarebunken bare brukt for avbrudd, og både PSP og RSP er adresseregister med generelle formål. (ANS Forth angir minst 32 celler av Parameter Stack og 24 celler av Return Stack Jeg foretrekker 64 celler av hver.) Du vil av og til støte på dogmaen som maskinvarebunken kvitterer for Parameter Stack, eller du kan få tilbake Return Stack. I stedet kodes noen eksempler fremfor primitive, for eksempel og se hvilken tilnærming som er mindre eller raskere. (DUP og DROP, forresten, er ingen test - de er vanligvis trivielle.) Noen ganger når du underlige konklusjoner Gary Bergstrom har påpekt at en 6809 DTC Forth kan gjøres noen få sykluser raskere ved å bruke 6809 brukerstabelpekeren som IP NEXT blir en POP. Han bruker et indeksregister for en av Forths stabler. Top-Of-Stack in Register Fremtidig ytelse kan forbedres betraktelig ved å holde toppelementet i Parameter Stack i et register. Mange Utgående ord (for eksempel 0) trenger ikke å bruke stakken. Andre ord gjør fortsatt det samme antallet pushes og pops, bare på et annet sted i koden. Bare noen få Forth ord (DROP og 2DROP) blir mer komplisert, siden du ikke lenger kan justere stakkpekeren - du må også oppdatere TOS-registeret også. Det er noen regler når du skriver CODE-ord: Et ord som fjerner elementer fra stakken må legge til quotnewquot-TOS i sitt register. Et ord som legger til elementer i stabelen, må skyve quotoetquot-TOS på bunken (med mindre det forbruker av ordet). Hvis du har minst seks CPU-registre i celleformat, anbefaler jeg at du holder TOS i et register. Jeg anser TOS mer viktig enn UP å ha i register, men mindre viktig enn W, IP, PSP og RSP. (TOS i register utfører mange av funksjonene i X-registret.) Det er nyttig hvis dette registeret kan utføre minneadressering. PDP-11s, Z8s og 68000s er gode kandidater. Ni av de 19 IBM PC Forths studert av Guy Kelly KEL92 holder TOS i register. Jeg tror at denne innovasjonen har blitt motstått på grunn av den falske oppfatningen at a) den legger til instruksjoner, og b) toppstakkelementet må være tilgjengelig som minne. Det viser seg at selv slike ord som PICK, ROLL og DEPTH blir trivielt modifisert for TOS-in-register. Hva med å buffere to stakkelementer i registre Når du holder toppen av stabelen i et register, blir det totale antallet operasjoner som utføres, stort sett det samme. Et trykk er et trykk, uansett om det er før eller etter operasjonen du utfører. På den annen side legger buffering av to stakkelementer i registre et stort antall instruksjoner - et trykk blir et trykk etterfulgt av et trekk. Bare dedikerte Forth-prosessorer som RTX2000 og utrolig smart optimaliserende kompilatorer kan dra nytte av å buffere to stablingselementer i registre. Noen eksempler Her er registeroppdragene laget av Forths for en rekke forskjellige CPUer. Prøv å utlede designbeslutningen fra forfatterne fra denne listen. quotSPquot refererer til harddiskpekeren. quotZpagequot refererer til verdier som holdes på 6502s minne side null, som er nesten like nyttige som - noen ganger mer nyttige enn - verdier holdt i registre, f. eks. de kan brukes til minneadressering. quotFixedquot betyr at Paynes 8051 Forth har et enkelt, ubrukelig brukerområde, og UP er en hardkodet konstant. Smalregistreringer Merk noe som er ukjent i forrige liste 6502 Forth - en 16-biters modell - bruker 8-biters stavepoints Det er mulig å lage PSP, RSP og UP mindre enn cellens størrelse på Forth. Dette skyldes at stablene og brukerområdet begge er relativt små områder av minnet. Hver stabel kan være så liten som 64 celler i lengde, og brukerområdet overskrider sjelden 128 celler. Du trenger bare å sikre at enten a) disse dataområdene er begrenset til et lite område med minne, så en kort adresse kan brukes, eller b) de høye adressebitene er gitt på en annen måte, f. eks. velg en minneside. I 6502 er maskinvarebunken begrenset til side 1 av RAM (adresser 01xxh) ved utformingen av CPU. 8-punkts pekepekeren kan brukes til Return Stack. Parameterstakken holdes på siden null for RAM, som kan indirekte nås av 8-biters indeksregister X. (Spørsmål til den avanserte studenten: hvorfor bruk 6502s X, og ikke Y Hint: se på adresseringsmodusene som er tilgjengelige. ) I 8051 kan du bruke 8-bitregistrene R0 og R1 til å adressere eksternt RAM, forutsatt at du eksplisitt sender ut de høye 8 bitene til adressen til port 2. Dette tillater en kvote seleksjon for to stabler. UP er forskjellig fra PSP og RSP: det gir bare en basisadresse, den blir aldri økt eller redusert. Så det er praktisk å levere kun de høye biter av dette virtuelle registeret. De lave bitene må da leveres med hvilken indeksert adresseringsteknikk som benyttes. For eksempel på 6809 kan du bruke DP-registeret til å holde de høye 8 bitene av UP, og deretter bruke Direct Page adressering for å få tilgang til noen av de 256 stedene på denne siden. Dette tvinger alle brukerområdene til å begynne på en adresse xx00h, noe som ikke er stor motgang, og begrenser brukerområdet til 128 celler i lengde. På 8086 kan du tenkelig bruke et segmentregister for å angi basisadressen til brukerområdet. REFERANSER CUR93a Curley, Charles, quotLife i FastForth Lane, citerer venter på publikasjon i Forth Dimensions. Beskrivelse av en 68000 subrutin-gjenget Forth. CUR93b Curley, Charles, quotOptimizing i en BSRJSR Threaded Forth, quote venter publikasjon i Forth Dimensions. Enkeltpass kodeoptimalisering for FastForth, i bare fem skjermbilder med kode Inkluderer notering. KEL92 Kelly, Guy M. quotForth Systems Comparisons, quot. Forth Dimensions XIII: 6 (MarApr 1992). Også publisert i 1991 FORML Conference Proceedings. Begge er tilgjengelige fra Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. Illustrerer designavvik fra mange 8086 Forths med kodefragmenter og benchmarks - sterkt anbefalt KOG82 Kogge, Peter M. quotAn Architectural Trail til Threaded Code Systems, citerer IEEE Computer, vol. 15 nr. 3 (mar 1982). Fortsetter den endelige beskrivelsen av ulike gjengeteknikker. ROD91 Rodriguez, B. J. quotB. Y.O. Assembler, sitat Del 1, The Computer Journal 52 (SepOct 1991). Generelle prinsipper for skriving Forth assemblers. ROD92 Rodriguez, B. J. quot. B.Y. O. Assembler, sitat Del 2, The Computer Journal 54 (JanFeb 1992). En 6809 assembler i Forth. SCO89 Scott, Andrew, quotAn Extensible Optimizer for Compiling Forward, citerer 1989 FORML Conference Proceedings. Forth Interest Group, P. O. Box 2154, Oakland, CA 94621. God beskrivelse av en 68000 optimaliserer ingen kode som er oppgitt. CUR86 Curley, Charles, Real-Forth for 68000. privat distribuert (1986). JAM80 James, John S. fig-Forth for PDP-11. Forth Interest Group (1980). KUN81 Kuntze, Robert E. MVP-Forth for Apple II. Mountain View Press (1981). LAX84 Laxen, H. og Perry, M. F83 for IBM PC. versjon 2.1.0 (1984). Distribuert av forfatterne, tilgjengelig fra Forth Interest Group eller GEnie. LOE81 Loeliger, R. G. Gjengetolkende språk. BYTE Publikasjoner (1981), ISBN 0-07-038360-X. Kan være den eneste boken som er skrevet om emnet for å skape en fremkalt kjernekode (eksempelet som brukes er Z80). Verdt det hvis du finner en kopi. MPE92 MicroProcessor Engineering Ltd MPE Z8Super8 PowerForth Mål. MPE Ltd. 133 Hill Lane, Shirley, Southampton, S01 5AF, U. K. (juni 1992). Et kommersielt produkt. PAY90 Payne, William H. Embedded Controller FORTH for 8051-familien. Academic Press (1990), ISBN 0-12-547570-5. Dette er en komplett kvotekvot for en 8051 Forth, inkludert en metakompiler for IBM PC. Hardcopy-filer kan lastes ned fra GEnie. Ikke for nybegynner SER90 Sergeant, Frank, Pygmy Forth for IBM PC. versjon 1.3 (1990). Distribuert av forfatteren, tilgjengelig fra Forth Interest Group. Versjon 1.4 er nå tilgjengelig på GEnie, og verdt den ekstra innsatsen å skaffe. TAL80 Talbot, R. J. fig-Forth for 6809. Forth Interest Group (1980). Forfatterens notat for webpublisering: Filene som tidligere var tilgjengelige på GEnie online-tjenesten, er nå tilgjengelig fra FTP-serveren Forth Interest Group, ftp: ftp. forth. orgpubForth. XanEdu gir tilpasset innhold, teknologi og tjenester for ledere i næringsliv og utdanning. Akademisk og profesjonelt læringsbehov endrer seg raskere enn noensinne. Siden 1999 har XanEdu hjulpet tusenvis av partnere til å tilpasse seg og trives ved å tilby den rette kombinasjonen av teknologi, innhold og dyktige profesjonelle tjenester for å støtte sine mål om å flytte læring fremover. Fra vår SAAS-baserte plattform for rask distribusjon av mobilt innhold, til dyktige redaksjonelle og publiseringstjenester for lærere, til overkommelige og engasjeringsløsninger for bokhandlere, gir XanEdu de enkle løsningene som hjelper våre partnere til å forberede morgendagens læringsbehov i dag. HVEM VI SERVER Oppdag en raskere vei til høyere ytelse med rask mobilinnholdsutplassering. Utvikle rimelige materialer så unike som institusjon, kurs og studenter. Skreddersy materiale til pensummål, kontrollkostnader og engasjere dagens mobil-sentriske studenter. Hold teamet ditt i tråd med kritisk policy, regulering og prosessendringer.

No comments:

Post a Comment