Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.
2022-08-03
För ett par veckor sedan skrev jag en kort text om hur man optimerar prestandan i Commodore BASIC 2.0 second release. Det gjorde att jag fick frågan om hur mycket man tjänar på att programmera maskinkod istället för BASIC. I mitt exempel drog jag ner exekveringstiden från 1522 jiffys (sextiondels sekunder) till 686 jiffys, genom att välja rätt kommandon och rätt strategi i en konstruerad uppgift: Spara tre värden i tre olika minnesadresser, 1000 gånger.
Uppgiften var att låta en VIC-20 skriva värdet 40 till adress 828, värdet 41 till adress 829 och värdet 42 till adress 830, ett tusen gånger, vilket alltså går att göra på 686 jiffys. Strategin för god prestanda måste utgå ifrån att realtidstolkning tar tid. Men så fick jag frågan om hur lång tid det tar för en VIC-20 att lösa samma uppgift om man skriver programmet i maskinkod. Jag gissade på nolltid, men rätt svar är 2 jiffys, alltså en trettiondels sekund.
Hur ser ett program, enligt ovan, konverterat till maskinkod ut? Stegenser ut som följer:
Jag väljer att lagra variabeln på adress 880-881 och lägga programmet på adress 831. På det viset ryms programmet mellan de tre adresser som är föremål för uppgiften (828-830) och variabeln som håller reda på antalet upprepningar (1000 stycken) på adress 880-881.
1. Assembler-koden för att initiera variabeln som håller räkning på antal körningar ser ut så här (adress 831):
LDA #0
STA 880
LDA #0
STA 881
2. Uppgiften är att skriva värdet 40 till adress 828, värdet 41 till adress 829 och värdet 42 till adress 830 (adress 841):
LDA #40
STA 828
LDA #41
STA 829
LDA #42
STA 830
3. Därefter ska variabeln som håller reda på antal skrivningar till minnet räknas upp (adress 856):
INC 880
BNE 864 ;(som är adressen till beslutet att iterera)
INC 881
4. Om uppgiften utförts färre än 1000 gånger, ska uppgiften upprepas (adress 864):
LDA 880
CMP #232
BNE 841
LDA 881
CMP #3
BNE 841
5. Avsluta.
RTS
Översatt till maskinkod, kan vi konstatera att vi har:
Om vi skriver en BASIC-loader för detta, och sedan tar tid på exekveringen, så ser koden ut så här:
10 FOR N=0 TO 47
20 READ V
30 POKE 831+N,V
40 NEXT
50 S=TI
60 SYS 831
70 PRINT TI-S
80 DATA 169,0,141,112,3,169,0,141
90 DATA 113,3,169,40,141,60,3,169
100 DATA 41,141,61,3,169,42,141,62
110 DATA 3,238,112,3,208,3,238,113
120 DATA 3,173,112,3,201,232,208,226
130 DATA 173,113,3,201,3,208,219,96
Och mycket riktigt har vi nu utfört samma uppgift på 2 jiffys istället för 686 jiffys. Maskinkod är alltså inte så lite snabbare än BASIC på VIC-20.
Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!
Leave a Reply