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

Discussion in 'C Programming' started by miloody, Nov 30, 2010.

  1. miloody

    miloody Guest

    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};
    }
    miloody, Nov 30, 2010
    #1
    1. Advertising

  2. miloody <> wrote:
    > 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
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Nov 30, 2010
    #2
    1. Advertising

  3. On Nov 30, 9:11 am, miloody <> wrote:
    > 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.
    Malcolm McLean, Nov 30, 2010
    #3
  4. On 2010-11-30, Jens Thoms Toerring <> wrote:
    > miloody <> wrote:
    >> 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);
    }
    ---
    compiles into yet another version, which does 4 64-bit memory reads and
    writes.

    Apologies for straying rather far off the topic of c.l.c.)

    --
    Heikki Kallasjoki
    email: echo 'zfs+es_t_i@n_u.zf' | tr zen_muftis fuze_mints
    Heikki Kallasjoki, Nov 30, 2010
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Adam Hartshorne

    Multi-Dimension Array Question

    Adam Hartshorne, Jun 8, 2005, in forum: C++
    Replies:
    6
    Views:
    2,133
  2. Makiyo
    Replies:
    3
    Views:
    530
    Richard Heathfield
    Feb 22, 2004
  3. Eric Laberge

    Multi-dimension array assignments

    Eric Laberge, Aug 22, 2005, in forum: C Programming
    Replies:
    3
    Views:
    449
    Dave Thompson
    Aug 27, 2005
  4. Replies:
    11
    Views:
    511
    Alexei A. Frounze
    Sep 29, 2005
  5. Luuk
    Replies:
    15
    Views:
    801
    Nobody
    Feb 11, 2010
Loading...

Share This Page