Sida 1 av 1

PIC: spara stackminne

Postat: 20 mars 2010, 21:43:53
av persika
Kom på ett litet tips för att spara stack- och program-minne och lite körtid med.

Istället för:

Kod: Markera allt

huvudprogram
		call rutin_A
		nop
slut		goto slut

rutin_A
		nop
		nop
		call rutin_B
		return
rutin_B
		nop
		nop
		return
Så kan man anropa rutin_B med goto istället, så hoppar den direkt tillbaka till huvudprogrammet, funkar bara när en rutin anropas sist i en annan rutin.

Kod: Markera allt

huvudprogram
		call rutin_A
		nop
slut		goto slut

rutin_A
		nop
		nop
		goto rutin_B
		; inget return behövs här
rutin_B
		nop
		nop
		return

Re: PIC: spara stackminne

Postat: 21 mars 2010, 00:06:25
av korp
Och kommer rutinerna att ligga på rad sådär så kan du ju spara in på "goto rutin_B" också förstås. :)

Re: PIC: spara stackminne

Postat: 21 mars 2010, 10:16:34
av Jonas L
Tyvärr måste jag säga att det är den typen av optimeringar som orsakar några av de värsta buggarna. Det kräver att man har stenkoll på vad man har i stacken, vilket är lätt när man gör programmet från början. När man går in efter ett par månader och ska fixa något eller bygga vidare så åker man dit om man inte följer konventionerna. T.ex. finns det personer dom gör två rutiner, låt oss kalla dem A och B. Normalt sett går A igenom och returnerar som vanligt. I något specialfall hoppar man rakt över i B och använder dess retursats. Efter att man har glömt denna fuling så går man in och lägger till en push i B. Då funkar allt tills specialfallet uppkommer och det krashar. Trots att man "inte har rört" den biten.

Re: PIC: spara stackminne

Postat: 21 mars 2010, 10:27:33
av Swech
Optimeringen är i sig ok, men bör undvikas om man inte har brist på programminne.
Däremot förstår jag inte Jonas L resonemang.
En push i B måste även inkludera en pop i B och returadressen
kommer att bevaras. Saknas pop i B så har man en bugg som krashar oavsett om man
anropar med call eller goto

Optimeringar som går ut på att hårdvaran ser ut på ett specifikt sätt är däremot av ondo.
T.ex. man har en ingång på en port som ligger på bit7. Istället för att testa om biten är satt
så kollar man om det är negativt, vilket bara funkar då det är bit7.
Kan vara oerhört tidskrävande om man reviderar hårdvaran och ändrar pinplacering.

Swech

Re: PIC: spara stackminne

Postat: 21 mars 2010, 10:52:27
av persika
Jag skrev inte att det gällde de mindre PIC'arna typ 16F676, och där finns inte push o pop, så det är iaf inte nåt problem där.

Håller med lite fulingprogrammering är det, men kan behövas ibland då man bara har 8 stacknivåer.

Re: PIC: spara stackminne

Postat: 21 mars 2010, 14:24:15
av Icecap
Mina tankar:
* Om en rutin (A) hoppar till en annan (B) direkt och ingen annan använder B ska de slås ihop till en samlat rutin.
* Om fler rutiner sluter med samma rutin kan de fint hoppa dit direkt, man måste då se till att kommentera tydligt att denna gemensamma ska hoppas till.

Helt standard programmeringsförfarande i "min värld" alltså...

Re: PIC: spara stackminne

Postat: 21 mars 2010, 15:33:49
av Nerre
En av de stora fördelarna med att t.ex. skriva i C är att kompilatorn, om det går, kan göra den typen av optimeringar. Då behöver man inte tänka på det själv, om det går så fixar kompilatorn det och om det inte går så låter den bli.

MEN, det som slår mig här nu, sparar man inte exakt lika mycket om man istället för den där goto-manövern helt enkelt anropar B efter att man anropat A?

Så istället för

Kod: Markera allt

Call A

Sub A
Foo
Goto B

Sub B
Bar
Return
så kör man

Kod: Markera allt

Call A
Call B

Sub A
Foo
Return

Sub B
Bar
Return
I bägge fallen kommer Foo och Bar utföras efter varandra.

Re: PIC: spara stackminne

Postat: 21 mars 2010, 18:44:56
av persika
Nerre>
MEN, det som slår mig här nu, sparar man inte exakt lika mycket om man istället för den där goto-manövern helt enkelt anropar B efter att man anropat A?


Jo, det är ju sant, men om A är en rutin i ett bibliotek av rutiner och B bara är en underrutin, så ska inte "användaren" behöva komma ihåg att B ska anropas efter A. Rutinen B kanske inte ska synas "utåt".