Alex
Alex

Reputation: 1124

C/C++ How a 3 dimensional array is stored in memory and what is the fastest way to traverse it

I am trying to understand how a 3 dimensional array is stored in memory and the difference between how std:vector is stored.

This is the way I understand that they are stored, and std::vectors, same way, with the difference that they make full use of memory blocks a[0][0][0] a[0][0][1] a[0][0][2]... a[0][1][0] a[0][1][1] ... a[1][0][0] a[1][0][1]...

My goal is to find which is the most efficient way to traverse and array.

For example, I have array:

v[1000][500][3];

so how is more efficient to traverse it?

for(i = 0; i < 1000; i++)
{
    for(j = 0; j < 500; j++)
    {
       for(k = 0; k < 3; ++k)
       {
           //some operation
       }

    }
}

or may be it would be more efficient to declare the array as;

v[3][500][1000]

and to traverse as

for(i = 0; i < 3; i++) { for(j = 0; j < 500; j++) { for(k = 0; k < 1000; ++k) { //some operation }

} }

Is there any CL tool to visualize how arrays are stored?

Upvotes: 1

Views: 2794

Answers (3)

user2249683
user2249683

Reputation:

To make it visible:

#include <iostream>

    int main()
    {
        int a[][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
        int* p = reinterpret_cast<int*>(a);
        for(unsigned i = 0; i < 6; ++i) {
            std::cout << *(p + i);
        }
        std::cout << std::endl;
        return 0;
    }

Shows a row major order - see: http://en.wikipedia.org/wiki/Row-major_order

Having this, you should iterate per row to utilize the cache. In higher dimension N you will get similar, where each element represents a block of data with a dimension N-1

Upvotes: 1

Eric Fortin
Eric Fortin

Reputation: 7603

You're right in your representation of arrays in memory values are contiguous. So an int v[2][2][2] initialized to 0 would look like:

[[[0, 0], [0, 0]], [[0, 0], [0, 0]]]

As far as performance goes you want to access data as close to each other as possible to avoid data cache misses so iterating on the outer most dimension first is a good thing since they are located next to each other.

Something that might happen though with your first example is the compiler might optimize the inner loop(if right conditions are met) and unroll it so you would save some time there by skipping branching.

Since both your example are already iterating in the right way, I would say profile it and see which is faster.


std::vector also store its element contiguous in memory but since it is 1 dimension, locality apply by default(provided you aren't iterating randomly). The good side of vector is they can grow whereas an array can't(automatically anyway).

Upvotes: 2

Peng Zhang
Peng Zhang

Reputation: 3585

When the memory address is continuous (e.g., complied time array a[][][]), the most efficient way to traverse a multidimensional array is use a pointer. The a[i][j][k] actually is &a[0][0][0]+(i*j*k + j*k + k). Thus, initialize a pointer p to the beginning address, then calls *(p++)

int main() {
    int a[2][3]={{1,2,3},{4,5,6}};
    int *p = &a[0][0];
    for( int i=0; i<6; ++i ){
        cout<<*(p++)<<endl;
    }
    return 0;
}

Upvotes: 1

Related Questions