how to fast set value of a multi-dimension array?

M

miloody

Dear all:
At the end of letter is my source code.
My questions are:
If I declare a global multi-dimension array, how could I assign it
value fast later in my local function?
I don't want to assign it one by one by for loop, since it seems quite
inefficient.
BR,
miloody

/*
ex1 is assign it at beginning.
ex2 is the wrong way.
*/

#include <stdio.h>
#include <stdlib.h>
int Array[3][8];
/* ex1
int Array[3][8] = {{0x80,0x06,0x00,0x02,0x00,0x00,0x08,0x00},
{0x00,0x05,03,0x00,0x00,0x00,0x00,0x00},
{0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00}};
*/
int main(void)
{
//ex2
Array[0] = {0x80,0x06,0x00,0x02,0x00,0x00,0x08,0x00};
}
 
J

Jens Thoms Toerring

miloody said:
If I declare a global multi-dimension array, how could I assign it
value fast later in my local function?
I don't want to assign it one by one by for loop, since it seems quite
inefficient.
/*
ex1 is assign it at beginning.

That's what's called "initialization".
ex2 is the wrong way.
*/
#include <stdio.h>
#include <stdlib.h>
int Array[3][8];
/* ex1
int Array[3][8] = {{0x80,0x06,0x00,0x02,0x00,0x00,0x08,0x00},
{0x00,0x05,03,0x00,0x00,0x00,0x00,0x00},
{0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00}};
*/
int main(void)
{
//ex2
Array[0] = {0x80,0x06,0x00,0x02,0x00,0x00,0x08,0x00};

That doesn't work since "assigning" to an array as a whole is
noot allowed. The only place something that looks similar is
allowed is during creation of an array, where you can supply
data to initialize it. What you could do is to create a tem-
porary array, initialized with those data, and then use mem-
cpy() to copy them to your array, i.e.

int tmp[ ] = {0x80,0x06,0x00,0x02,0x00,0x00,0x08,0x00};
memcpy( &Array[ 0 ], tmp, sizeof Array[ 0 ] ),

But I would doubt a bit that this is much faster than a for
loop, at least with such short arrays.

If you have to do something like this very often then you
might question yourself if an 2-dimensional array is the
right thing to use or if perhaps an array of pointers to
int arrays wouldn't be more suitable for the problem since
changing where a pointer points to is cheap while copying
arrays is typically more expensive. Of course, that has
some other restrictions, e.g. you can't assign it a pointer
to a locally defined array which goes out of scope at the
end of the function and then try to access that after-
wards...
Regards, Jens
 
M

Malcolm McLean

Dear all:
At the end of letter is my source code.
My questions are:
If I declare a global multi-dimension array, how could I assign it
value fast later in my local function?
I don't want to assign it one by one by for loop, since it seems quite
inefficient.
This is C.

Loops are usually as efficient as it gets. The processor usually needs
to loop, regardless of programming language, and the C statements will
compile to very efficient machine code.
 
H

Heikki Kallasjoki

miloody said:
If I declare a global multi-dimension array, how could I assign it
value fast later in my local function?
I don't want to assign it one by one by for loop, since it seems quite
inefficient. [..]
Array[0] = {0x80,0x06,0x00,0x02,0x00,0x00,0x08,0x00};

That doesn't work since "assigning" to an array as a whole is
noot allowed. The only place something that looks similar is
allowed is during creation of an array, where you can supply
data to initialize it. What you could do is to create a tem-
porary array, initialized with those data, and then use mem-
cpy() to copy them to your array, i.e.

int tmp[ ] = {0x80,0x06,0x00,0x02,0x00,0x00,0x08,0x00};
memcpy( &Array[ 0 ], tmp, sizeof Array[ 0 ] ),

But I would doubt a bit that this is much faster than a for
loop, at least with such short arrays.

FWIW (and it's not W much), my particular version of gcc on this
particular machine, with -O3, for the following two functions:

---
#include <string.h>
extern int array[3][8];

void update_array1(void)
{
int values[8] = {0x80, 0x06, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00};
int i;
for (i = 0; i < 8; i++)
array[0] = values;
}

void update_array2(void)
{
int values[8] = {0x80, 0x06, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00};
memcpy(array[0], values, sizeof values);
}
---

.... generates somewhat different code. To summarize, in update_array1
it has opted to unroll the loop into 8 "movl" instructions that move a
constant 32-bit value into array+offset; for update_array2 it instead
decided to first move those constants to stack, then use 64-bit "movq"
instructions to move the data (via a register) to the array. One
speculates this is because the built-in memcpy insists on having an
address to copy values from. As always, which one is faster probably
depends on the circumstances, but it's not too far-fetched to think that
the simple loop might easily win here.

(Incidentally, in case the values are constant like that,
---
void update_array3(void)
{
static const int values[8] = { /* ... */ };
memcpy(array[0], values, sizeof values);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top