如何 提高C++ 多维数组访问速度

碎碎念 2013-11-20 04:14:07
rt,假设数组维度为4,A*B*C*D,大小 512*512*100*120(即A=521,B=512,C=100, D=120),在堆上分配内存,如果分配和管理这部分内存能够使得,按不同维度来访问数组都能获得较快的访问速度?比如说,按照如下方式分配内存:
int ****A;
A = new int ***[512];
for(int i = 0; i < 512; i++)
{
A[i] = new int**[512];
}
for(int i = 0; i < 512; i++)
for(int j = 0; j < 512; j++)
{
A[i][j] = new int*[100];
}

for(int i = 0; i < 512; i++)
for(int j = 0; j < 512; j++)
for(int k = 0; k < 100; k++)
{
A[i][j][k] = new int[120];
}
按照维度D访问数组,由于最后一个维度,所以访问的内存地址是连续的,缓存命中率较高,但是按照维度C,访问数组,由于内存地址的不连续,会导致内存颠簸,有什么方式可以提高多维数组的访问速度?可以使用不同的内存分配方式,主要是需要按照不同维度访问数组都可以获得较高的访问速度速度?
...全文
988 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-11-25
  • 打赏
  • 举报
回复
引用 13 楼 lanxue_1988 的回复:
[quote=引用 12 楼 zhao4zhong1 的回复:] 8、9楼正解!
假如多维度A,C访问,遍历A[i][0][j][0],这样访问的内存跳跃较大,是不连续的,如果把数组的维度做一下调整变成B*D*A*C,这样遍历A[0][0][i][j],访问的速度会有提升,有没有好的办法对数组的维度做出调整?[/quote] 无需调整。 不要低估CPU内部两级Cache的智商!
碎碎念 2013-11-25
  • 打赏
  • 举报
回复
引用 12 楼 zhao4zhong1 的回复:
8、9楼正解!
假如多维度A,C访问,遍历A[i][0][j][0],这样访问的内存跳跃较大,是不连续的,如果把数组的维度做一下调整变成B*D*A*C,这样遍历A[0][0][i][j],访问的速度会有提升,有没有好的办法对数组的维度做出调整?
赵4老师 2013-11-22
  • 打赏
  • 举报
回复
8、9楼正解!
碎碎念 2013-11-22
  • 打赏
  • 举报
回复
引用 2 楼 dyw 的回复:
C/C++ tip: How to loop through multi-dimensional arrays quickly http://nadeausoftware.com/articles/2012/06/c_c_tip_how_loop_through_multi_dimensional_arrays_quickly
谢啦~ 还有个问题,对于,10楼我说的问题,有没有什么好的解决方式?~
碎碎念 2013-11-22
  • 打赏
  • 举报
回复
引用 3 楼 supermegaboy 的回复:
http://blog.csdn.net/code_crash/article/details/4854899 你现在的做法是先组合地址再分配内存,内存是不连续的,可以改为先分配内存再组合地址,可能可以提高命中率。 此外,这些数组的元素需要参与计算么?是的话,可以考虑表达式模板减少临时对象,提高性能。
博客写得很受用~谢啦 还有个问题。 采用如下方式

int *pBuf = new int[512*512*120*100];
int **p1 = new int*[512*512*120];
int ***p2 = new int**[512*512];
int ****A = new int***[512];
for(int i = 0; i<100; i++)
   p1[i] = pBuf + 512*512*120*i;
for(int i = 0; i< 120;i++)
   p2[i]=p1+512*512*i;
for(int i =0; i<512;i++)
   A[i]=p2+512*i;
分配的地址是连续的,假如,程序在某段时间内,频繁访问维度AC,比如遍历A[i][0][j][0],遍历i,j时,访问的内存不是连续的,这个时候有没有什么办法能够提高访问速度? 之前,我想得是在访问维度AC之前,可以将数组维度变换为B*D*A*C,然后对维度A*C进行访问,但是没有想出什么好的办法对数组维度进行变换,有没有什么好的办法处理这种情况?
赵4老师 2013-11-20
  • 打赏
  • 举报
回复
ARR[i*512*100*120+j*100*120+k*120+l]='V';//ARR[i][j][k][l]='V'
赵4老师 2013-11-20
  • 打赏
  • 举报
回复
纠正上帖:
int *ARR=new int[512*512*100*120];
int *A,*B,*C,*D;

for (A=ARR;A<ARR+512*512*100*120;A+=512*100*120) A[0]='A';//ARR[0..511][0     ][0   ][0     ]='A'
for (B=ARR;B<ARR+  1*512*100*120;B+=    100*120) B[0]='B';//ARR[0     ][0..511][0   ][0     ]='B'
for (C=ARR;C<ARR+      1*100*120;C+=      1*120) C[0]='C';//ARR[0     ][0     ][0.99][0     ]='C'
for (D=ARR;D<ARR+          1*120;D+=          1) D[0]='D';//ARR[0     ][0     ][0   ][0..119]='D'
赵4老师 2013-11-20
  • 打赏
  • 举报
回复
int *ARR=new int[512*512*100*120];
int *A,*B,*C,*D;

for (A=ARR;A<A+512*512*100*120;A+=512*100*120) A[0]='A';
for (B=ARR;B<B+  1*512*100*120;B+=    100*120) B[0]='B';
for (C=ARR;C<C+      1*100*120;C+=      1*120) C[0]='C';
for (D=ARR;D<D+          1*120;D+=          1) D[0]='D';
gz_qmc 2013-11-20
  • 打赏
  • 举报
回复
typedef struct X { int V[120]; }MX; typedef struct Y { MX V[100]; }MY; typedef struct Z { MY V[512]; }MZ; typedef struct N { MZ V[512]; }MN; MN *A=new MN; A->V[i].V[j].V[k].V[n]=7788;
Exaybachay 2013-11-20
  • 打赏
  • 举报
回复
提高速度就是快速的寻址, 多维数组类似数据库表了, 你建索引
gz_qmc 2013-11-20
  • 打赏
  • 举报
回复
A[i][j][k][n] 表示为 A[512*i+512*j+100*k+n];
dyw 2013-11-20
  • 打赏
  • 举报
回复
飞天御剑流 2013-11-20
  • 打赏
  • 举报
回复
http://blog.csdn.net/code_crash/article/details/4854899 你现在的做法是先组合地址再分配内存,内存是不连续的,可以改为先分配内存再组合地址,可能可以提高命中率。 此外,这些数组的元素需要参与计算么?是的话,可以考虑表达式模板减少临时对象,提高性能。
gz_qmc 2013-11-20
  • 打赏
  • 举报
回复
int *X=new int(512*512*100*120);

64,701

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧