访问双 std::array 的元素

Accessing elements of a double std::array

本文关键字:元素 array 访问 std      更新时间:2023-10-16

我的问题是关于访问双std::array元素的效率。由于std::array是一个静态大小的容器,我希望它的数据存储在连续的内存块中,并且访问std::array的元素与 C 样式数组相同。使用std::array不应增加任何额外的开销。

访问双数组的元素是否std::array<std::array<T,N>,M>优化?

例如,我必须在下面源代码。

#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. a是否使用单个内存块?
  2. 访问具有常量索引(即a[1][3])的元素是内存中的单移还是双移?
  3. 访问循环中的元素需要多少个班次(即a[1][j])

我在上面的示例中使用了 godbolt.org 来检查汇编代码,似乎gcc -O4做得很好。

例如,对a[1][3]a[0][1]的访问被编译为:

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

但是,我可以在更复杂的示例中使用此发现吗? 还是应该坚持简单的std::arrays来控制访问效率?

std::array中是否有任何ISO标准描述?

  1. 是的,它位于连续的内存块中
  2. 不涉及移位,在优化甚至非优化的代码中不涉及移位(除了可能用于索引成一维数组的简单移位)。std::array与常规 C 样式数组的不同之处在于,编译器无法确定数组在内存中的布局方式(即行是排在第一位还是列,大多数编译器按行顺序布置它,但这并不重要),如何解析索引(是否涉及任何乘法"移位"), 等。 它是一个简单的一维数组,其中每个元素都是给定的类型(在您的情况下,每个元素本身都是一个数组)。 下面的示例应该演示我所说的内容。
  3. 无班次,见上文和下文

#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;
}