Accessing elements of a double std::array

时间:2017-06-15 09:54:46

标签: c++ arrays c++11 stl

My question is about efficiency of accessing elements of a double std::array. Since the std::array is a static-sized container, I expect its data to be stored in a continuous block of memory and accessing the elements of the std::array to be same as C-style arrays. The use of std::array should not add any additional overhead.

Is accessing elements of double arrays std::array<std::array<T,N>,M> optimised?

For example I have to source code below.

#include <array>
#include <random>

int main(){
  std::array<std::array<int,4>,2> a;

  for(int j=0;j<4;j++)
    a[0][j] = rand();

  for(int j=0;j<4;j++)
    a[1][j] = rand();

  int r = a[0][1] + a[1][3];
  return r;
}
  1. Does a uses a single block of memory?
  2. Is accessing an element with constant indices (ie a[1][3]) a single or a double shift in memory?
  3. How many shifts is needed in accessing the element in a loop (ie a[1][j])

I used godbolt.org in the above example to check the assembly code and it seems that gcc -O4does a pretty good job.

For example access to a[1][3] and a[0][1] is compiled as :

    mov     eax, DWORD PTR [rsp+28]
    add     eax, DWORD PTR [rsp+4]

However can I use this finding in a more complex example? Or should I stick to simple std::arrays to control access efficiency?

Is there any ISO standards description in the double std::array?

1 个答案:

答案 0 :(得分:0)

  1. Yes it is in a contiguous block of memory
  2. There is no shifting involved, there will be no shifting involved (other than the simple one possibly used to index into a one dimensional array if at all) in optimized or even non-optimized code for that matter. std::array differs from regular C style arrays in that it is not up to the compiler to determine how the array will be laid out in memory (i.e. whether the rows will be first or the columns, most compilers lay it out in row order but that is not important), how indexing will be resolved (whether any multiplicational "shifts" will be involved), etc. It is a simple one dimensional array where each element is of a given type (in your case, each element is an array itself). The following example should demonstrate what I am saying.
  3. No shifts, see above and below

#include <iostream>

using std::cout;
using std::endl;

template <int size>
using int_arr = int[5];

int main() {
    // an array of 5 arrays, unlike int arr[5][5]; 
    int_arr<5> arr[5];

    // first operator[] will resolve to the first array, return a 
    // reference to it and then the second will resolve to the correct
    // integer.  Similar to ((arr[0])[0])
    arr[0][0] = 12;
    cout << arr[0][0] << endl;

    return 0;
}