So the questions now are, does SDCC compile multidimentional arrays, and would the performance be effected?
i cannot answer the first part at this time. but the second part is that the extra look up does have an effect on performance.
let me explain
btw the times are only approximates from by experience with 80x86 assembly, if someone knows the actual times, it would be appreciated.
for an ordinary variable say an int, the lookup would be 1 cycle, just recalling the value stored by the variable (at a specified memory location).
for an one dimensional array, the lookup would be about 3-4 cycles
lookup the pointer to the array, add the offset, and retrieve the value
for a two dimensional array, the lookup would be about 6-8 cycles
lookup the pointer to top level array, add the offset, retrieve pointer to second level array, add 2nd level offset, retrieve the data.
for a three dimensional array, the lookup would be about 9-12 cycles
lookup the pointer to top level array, add the offset, retrieve pointer to 2nd level array, add 2nd level offset, retrieve pointer to 3rd level array, add the offset, retrieve the data.
as you can see, as you go deeping into a multidimensional array, the cost can become quite large if it is done frequently. this can be offset with the use of temporary variables, particularly in loops (which is where the use of arrays if often done).
other advantages of multidimensional arrays include the simplification of code (i will not say easier to debug because any problems avoided by keeping related data in the multidimention array is offset by different potential bugs).
lets have a look a the difference with some code:
for demonstation purposes, i will show some differences between 1 and 2 dimensional arrays:
1 dimension:
int do = {1,2,3,4,5};
int rei = {2,3,4,5,6};
int me = {0,9,8,7,6};
int i,j;
for (i = 0; i < 5; i++)
{
for (j = 0; i < 5; j++)
{
do = i + j;
rei = i + j;
me = i + j;
}
}
2 dimensions:
int do[] = {1,2,3,4,5};
int rei[] = {2,3,4,5,6};
int me[] = {0,9,8,7,6};
int* scale[3];
scale[0] = do;
scale[1] = rei;
scale[2] = me;
int i,j,.k;
for (i = 0; i < 5; i++)
{
for (j = 0; i < 5; j++)
{
for (k = 0; k < 3; k++)
{
scale[k]__[j] = i + j;
}
}
}
now both examples do the same task, but if you extend the number of array elements to 20, 30 or more, the first example would become large, unwieldy and bugprone as you create more arraynames and need to remember which to include in your calculations and in what order. on the other hand, the second example would only need a small amount of modification and continue to do its task.
just remember that with the 18F452, every assembly opperation takes 1 clock cycle except branches (jumps) which take 2 cycles. as you can see in the examples, the first example can become unwieldy if its size increases. but the second example with slow down as more lookups and branches occur (each iteration of a loop requires a branch function in assembly).
additionally you will also need to consider the speed of the processor, the 18F452 is rated at 10 MIPS (million instructions per second) so it if don’t go overboard in creating large arrays and looping through them with abondon, the overall effect would be negligable.
personally, i would first get my code to work correctly using deep nested arrays if necessary. then if needed, i would reexamine the code and introduce optimisations such as temporary variables and unwinding array nests in order to get the code faster. it is quite possible to double the size of your code and only improve the program speed by 5-10 percent.
just remember when optimising your code - always keep backups of your code!!! that way you can discard optimisations that don’t work - never hope you can undo the changes you make when you find the changes don’t work.
I know this was a bit verbose but i wanted to provide some of the reasons to use multidimensional arrays and some of the pitfalls.
OrganGrinder