Hello everyone,

I wrote a bunch of recursive functions to operate on multi-dimensional

matrices. The matrices are allocated dynamically in a non-contiguous way,

i.e. as an array of pointers pointing to arrays of data,or other pointers

if the matrix has more than 2 dimensions.

The parameters passed to these functions are:

- current_dimension: counts (from 0 to dimensions-1) the matrix

dimension on which the function is working, it's the variable passed on

the stack by the recursion

- dimensions: number of matrix's dimensions

- elem_size: size of the matrix's elements

- dimensions_sizes: a vector containing the 'size' of each dimension

For example, to work on a 10x20 matrix of integers, following the

ordering of above, we would pass:

(0,2,sizeof(int),(unsigned int [2]){10,20})

for a 10x20x15 one, we would pass

(0,3,sizeof(int),(unsigned int [3]){10,20,15})

The functions work fast for allocation and freeing, 'cause calls to

malloc and free take up most of the execution time. They're somewhat slow

at copying or initialising matrices. For initialization I mean assign a

scalar value to the elements of the matrix.

I've done some benchmarks with copying and initialisation. Compared to a

specific-nested-loop solution, the functions take up to twice the time.

However, turning on some optimization flags, specifically '-O3' with gcc,

the gap between the recursive and the specific solution reduces to 20%.

So, have you got any advice about optimizing this code?

Other suggestions are welcomeas well.

TIA

Andrea

Here follows the copying function. The initialising function is almost

identical

NB: to better understand the code you should imagine to work with a bi-

dimensional matrix (implemented as a pointer to pointer in the code). The

recursive step casts either the matrix to a vector, if the function

reached the elements' dimension, ending recursion, or the rows of the

matrix to a bi-dimensional matrix (again, pointer to pointer), continuing

recursion.

//////////////////////////////////

typedef unsigned char byte;

// this one copy one row of the matrix. The row is supposed to store the

value of elements, not pointers

void _copy_row(void* dest, void* src, unsigned short elem_size, unsigned

int n)

{

unsigned short length;

byte* d1,*d2;

d1 = (byte*)dest;

d2 = (byte*)src;

// copy byte to byte

while (n > 0)

{

for (length = 0; length < elem_size; length++)

{

(*d1) = (*d2);

d1++;

d2++;

};

n--;

};

}

// this is the recursive function

void _vec_copy(byte current_dimension, byte dimensions,unsigned short

elem_size, unsigned int* dimensions_size, void** restrict dest, void**

restrict src)

{

int i; // row index

if (current_dimension < dimensions)

{

if (current_dimension == dimensions -1)

{

_copy_row((void*)dest, (void*)src, elem_size,dimensions_size

[current_dimension]);

}

else

{

for (i = 0; i < dimensions_size[current_dimension]; i++)

_vec_copy(current_dimension+1, dimensions,

elem_size,dimensions_size, (void**)dest[i], (void**)src[i]);

};

};