How is array-access compiled?

BlitzMax Forums/BlitzMax Beginners Area/How is array-access compiled?

ImaginaryHuman(Posted 2004) [#1]
I am just wondering, if you set up an array for example...


Local myarray:Int[50]

and then you want to access it with...


For Local i:int=0 to 49
   Print myarray[i]
Next

does BlitzMax compile this down to being `hardcoded` to access that array in 4-byte increments? Or does it have to check the type of the array on every access and multiple that size by the offset (plus the base) to get to the data? Or is it more hardcoded - ie it multiplies i by 4 and adds it to the base address then reads?

Also, would it be faster then to use an array of Bytes rather than an array of Ints, so that the multiplication (or left shift) to jump to the appropriate location can be eliminated?


PowerPC603(Posted 2004) [#2]
When you compile this code, BMax generates an assembler-code file.
As far as I can tell (and as far as my knowledge goes for assembler), it seems that the type of the array is analysed during runtime.

I've compiled this code:
FrameWork BRL.Basic

Local myarray:Int[50]


This gives the smallest code.

Inside this assembler-code file (untitled1.bmx.d.s), there are only 2 lines that change, when you change the type of the array from Int to Byte:
_17
	db	"[]i",0
_11
	db	"i",0


Those change to:
_17
	db	"[]b",0
_11
	db	"b",0


When the For Next loop is included, this block is changed when it's an Int-array:
_21:
	mov	eax,dword [ebp-4]
	movzx	eax,byte [eax+ebx+24]
	mov	eax,eax
	push	eax
	call	_bbStringFromInt
	add	esp,4
	push	eax
	call	_brl_standardio_Print
	add	esp,4

To
_21:
	mov	eax,dword [ebp-4]
	push	dword [eax+ebx*4+24]
	call	_bbStringFromInt
	add	esp,4
	push	eax
	call	_brl_standardio_Print
	add	esp,4


For printing the contents of the array, it seems that it jumps 4 bytes (hardcoded) for an Int and only 1 byte for a Byte array.


ImaginaryHuman(Posted 2004) [#3]
Hmm ok, so maybe the bytes are a bit faster then. Having said that, on a PowerPC most instructions run in 1 cycle so even if it is a more complex instruction like including the *4, maybe it makes no difference.


PowerPC603(Posted 2004) [#4]
I think you won't notice the difference in access-time.

Maybe when you're about to read from that array for about 1.000.000 times per frame and you want to have your game running at 50fps, maybe then you will see the difference.

My nickname may suggest that I own a PowerPC processor, but I don't.
In my Amiga days, I always dreamed of buying the BlizzardPPC 1260 turboboard (with 68060 AND PPC 603e), that's where my nickname comes from.

But that's another story...
:-)


ImaginaryHuman(Posted 2004) [#5]
Well, conservative estimate, I may need to call these function pointers, say, at least several thousand times per frame at a high frame rate.

Re Amiga, yah I never got further than a 25Mhz 68040, and a PPC even at a few hundred Mhz seemed super fast. Now I'm enjoying a 300Mhz G3 and a 1GHz G4, which even though it's by no means top of the line, sure lets you do a lot more stuff.


jhague(Posted 2004) [#6]
If you're calling several thousand function pointers per frame, then some extra instructions in the calling sequence are not going to matter. They'll likely fall into holes in the pipeline anyway. They'll be dwarfed by cache issues and branch mispredictions...and what you're doing in each of the functions.


Bot Builder(Posted 2004) [#7]
Internally there is no type checking. It just acceses the 4 bytes, gives you the value. In the case of an array of strings its just pointers to the strings. Same for objects, and shock and horrer, ARRAYS OF ARRAYS! :P


PowerPC603(Posted 2004) [#8]

Re Amiga, yah I never got further than a 25Mhz 68040, and a PPC even at a few hundred Mhz seemed super fast. Now I'm enjoying a 300Mhz G3 and a 1GHz G4, which even though it's by no means top of the line, sure lets you do a lot more stuff.



I started from an A500, then bought a A1200 (14MHz 68020) and installed a Blizzard 1260 (68060 50MHz) with 32Mb RAM + SCSI-II controller.
I could open DirectoryOpus (kinda like Windows Explorer) about 9 times, before running out of graphical memory (2Mb) on a res of 1024x256 (couldn't use 1024x512, because of the flickering).

Try that on a pc.

Back then I had also a pc (Pentium MMX 180MHz) and it seemed that with some programs, my Amiga was faster.

Now I've got a P4 2.4GHz and my Amiga is only used for scanning pictures with my flatbad scanner (+/- once a year).



But back to the topic: Those lines, that hold the "[]b" and "[]i", for what purpose are they used then?
Is it just to indicate the type of pointer (to indicate that the arrays points to bytes or integer objects)?


ImaginaryHuman(Posted 2004) [#9]
Oh. Started with an A500, got a 1/2 meg upgrade, then a 2meg upgrade, then an A1200, then an Apollo A1240 (i think), then put it all in a tower with a graphics card. Yes Amiga's were cool, but in terms of gfx power or resolution most modern systems are faster now.


{cYan|de}(Posted 2004) [#10]
1024x256.. lol squashed?:P


ImaginaryHuman(Posted 2004) [#11]
Yah, that sounds like `superhires`... and it wasnt 1024 it was 1280x256. or 1280x512 with interlacing. Actually, A1200 could do 640x512 non-interlaced I think


Hotcakes(Posted 2004) [#12]
Remember you scroll screens sideways in AmyOS so he could have set his screensize to any res irrespective of the actual resolution. I constantly used a multiscan screenmode that was 2 or 3 screens in width...