我试图了解三维数组是如何存储在内存中的,以及存储std:向量的方式之间的区别。
这就是我所理解的存储它们的方式,而std::向量也是这样,不同的是它们充分利用内存阻止a1 a2.a1 ..。a1 a11..。
我的目标是找出哪种方式是最有效的方式遍历和排列。
例如,我有数组:
v[1000][500][3];
那么,如何更有效地遍历它呢?
(i= 0;i< 1000;i++) { for(j = 0;j< 500;j++) { for(k = 0;k< 3;++k) {//某些操作}}
或者可能更有效地声明数组为;
v31000 和横穿 对于(i= 0;i< 3;i++) { for(j = 0;j< 500;j++) { for(k = 0;k< 1000;++k) {//某些操作} }}
是否有任何CL工具来可视化数组的存储方式?
发布于 2014-02-15 04:11:02
在内存值中表示数组是连续的,这是正确的。因此初始化为0的int v22如下所示:
[[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
就性能而言,您希望尽可能接近彼此访问数据,以避免数据缓存丢失,因此,首先在最外层的维度上迭代是一件好事,因为它们位于彼此的旁边。
虽然第一个例子可能会发生一些事情,但编译器可能会优化内部循环(如果满足了正确的条件)并展开它,这样就可以通过跳过分支来节省一些时间。
由于您的两个示例都已经以正确的方式迭代,所以我会说,请对它进行分析,看看哪个更快。
向量还将其元素连续存储在内存中,但由于它是一维的,所以默认情况下会应用局部性(前提是不随机地迭代)。矢量的好处是它们可以生长,而数组不能(无论如何都是自动的)。
发布于 2014-02-15 04:09:07
当内存地址是连续的(例如,已编码的时间数组a[])时,最有效的遍历多维数组的方法是使用a pointer
。a[i][j][k]
实际上是&a[0][0][0]+(i*j*k + j*k + k)
。因此,初始化指向起始地址的指针p
,然后调用*(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;
}
发布于 2014-02-15 04:35:06
为了使它可见:
#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;
}
显示行的主要顺序-请参阅:order
有了这种情况,您应该迭代每一行以利用缓存。在更高的维度N中,您将得到类似的结果,其中每个元素表示一个维为N1的数据块。
https://stackoverflow.com/questions/21793078
复制相似问题