Ultimate Amiga
Network Boards => AMOS Factory => Extensions Forum => Topic started by: Hungry Horace on April 07, 2010, 05:53:35 PM
-
I read on here:
http://www.amigacoding.com/index.php/AMOS:Optimizing_Coding_Style (thanks Spellcoder) that Peek Poke etc are rather slow.
Does anyone know of any extensions with faster alternatives? i cant see anything in Turbo Plus or AMCAF to do it?
Basically, i used to be using arrays, but i thought it might be better to store/restore my 12 or so variables into memory, at different locations for my 4 game characters. Would it be quicker just using arrays like Hero_X(4) or using memory storage like this?
basically instead of
for hero=1 to 4
hero_x(hero)=200
hero_y(hero)=12
.. (and loads of other stuff)
next hero
i am using
for hero=1 to 4
Restore Variables from address (peek)
hero_x=200
hero_y=12
.. (and loads of other stuff)
Store Variables in address (poke)
next hero
any thoughts / advice? I dont want to waste time trying a mass find/replace job, if there is a faster PEEK/POKE command i can use, or if someone has any 'top tips' of which i'm not aware - I'm not convinced about arrays being any faster from what i've read.
-
The reason that Leek and Loke are supposed to be faster than array indexing is that there are no range checks on Leek and Loke.
The reason the Peek and Poke functions are slow is that Amos maintains a separate stack for all of its parameter passing. The only way to make them go faster is to switch to a better compiler that does register-loading optimizations. I'm sorry to have to be the bearer of bad news but that's how it goes. :(
BTW, if you're waiting for Mattathias, the Peek and Poke functions will not be directly supported except for areas of memory allocated as memory banks. That's a small price to pay for a memory-protected operating system support though.
-
thanks for the background info SamC - are you saying i should use leek/loke in all instances?
or should i be using arrays of 4 instead of poke/doking 10+ variables 4 times over?
i found a 'peek' command in a french extension, but surprisingly no 'poke' command to go with it. my french is not great, but i dont think it says anything about it being faster anyway.
(http://amos.condor.serverpro3.com/tp-images/FrenchPeek.png) (http://amos.condor.serverpro3.com/tp-images/FrenchPeek.png)
Mattathias isnt much good to me, as I'm trying to make the game run at a suitable speed on an emulated a500 setup (ergo, non-AGA), although i always allocate space before peeking/poking etc anyway.
I've found lots of other optimisations, but it is this and one other factor which i believe may be slowing the overall game code (i may discuss that in another thread)
-
If you know that you're going to be running on an emulated A500, and if your values are in the range of 0-65535 you should use Deek and Doke since they will take half the amount of memory and half the read and write time. You might be able to read with that Wb Peek instruction also but I don't know how it could possibly be faster than Deek unless Deek checks for odd addresses and disallows them.
-
If you know that you're going to be running on an emulated A500, and if your values are in the range of 0-65535 you should use Deek and Doke since they will take half the amount of memory and half the read and write time. You might be able to read with that Wb Peek instruction also but I don't know how it could possibly be faster than Deek unless Deek checks for odd addresses and disallows them.
ah, you didnt mention Deek/Doke before, so i had assumed they fell into the 'range checked' category like Peek/poke and were therefore slow.
i will give Deek/Doke a try and see if it helps - thanks again.
-
Do you think loading your info into a dim variable would give a speed increase over Deeking?
-
I have a question (about this tip):
MyTableBase=VarPtr(MyTable)
Now instead of accessing the array through AMOS with A=MyTable(10) access it directly yourself like this A=Leek(MyTableBase+40). The 40 is the offset for element 10, multiplied by the integer size, 4.
Dim Mytable(20)
Mytable(10)=99
A=Leek(MyTableBase+40)
Print A
The output should be : 99 insn't it ?
-
Yes. But you've got to have that MY_TABLE_BASE=VarPtr(MY_TABLE) after Dim MY_TABLE(20) so that you've got a stable address to reference. AMOS won't give MY_TABLE a base address until it's been declared. And remember that all AMOS arrays are base zero so they start at element ArrayName(0). That works fine for working out the address of an element as it's simply ElementNumber * 4.
So
Dim MY_TABLE(20)
MY_TABLE_BASE=Varptr(MY_TABLE)
MY_TABLE(10)=99
A=Leek(MY_TABLE_BASE+40)
Print A
If you're always going to reference the array using Leek and Loke, you can simply allocate the required memory yourself with a work bank:
MY_TABLE=20
Reserve As Work MY_TABLE,84
MY_TABLE_BASE=Start(MY_TABLE)
Loke MY_TABLE_BASE+40,99
A=Leek(MY_TABLE_BASE+40)
Print A
This allocates bank number 20 to hold the 84 bytes needed for the 21 element array that Dim MY_TABLE(20) would declare.
-
Sorry, I forgot the Varptr command :)
Anyway, I wanted to point out that it wasn't outputting the right value.
I have saved your 1st code in ASC file and loaded it into AmosPro and launched. The output value is 45 in my case :)
I use the reserved bank trick (easier) but I tought it was faster without using a bank, even if the bank is in fast ram (if the amiga got fast ram).
-
Oops, sorry. I should have saved in ascii instead of re-typing it:
Dim MY_TABLE(20)
MY_TABLE_BASE=Varptr(MY_TABLE(0))
MY_TABLE(10)=99
A=Leek(MY_TABLE_BASE+40)
Print A[/font][/b]
It's the address of the zeroeth element of ArrayName(0) that's needed. Using Varptr against just the ArrayName gives an indeterminate value. (Which, I suppose, I should record as a bug and fix it ::) Generate a "Syntax Error" during verification (Test/Run) maybe?).
-
No error. Just wrong output.
I guess the amigacoding article needs to be corrected too :)
-
Using Varptr against just the ArrayName gives an indeterminate value. (Which, I suppose, I should record as a bug and fix it ::) Generate a "Syntax Error" during verification (Test/Run) maybe?).
Not sure what you mean by indeterminate value, but it should return a pointer to a null value, as ArrayName on it's own would be classed as a variable, wouldn't it??? (It's been a while since I have coded anything in AMOS, so I'm not 100% sure that I'm right)