这是我第一次使用SO。对不起我的英语,但我会努力尽我所能,并完全为了您的理解,用我的大学任务来描述我的问题。我相信我的问题是更多的代码和数组相关,而不是数学。如何连续(连贯地)在C++内存中存储三维数组?
我正在使用MPI,OpenMP和大尺寸以及网格大小解决立方体中的数值3D波浪问题。现在我正在编写一个代码在我们的大学超级计算机上执行它。
因此一些小的解释和公式来理解问题更好:
- 我有在每个轴上的N + 1个点的立方体(与数字从到Ñ)
- 让我小号 = MPI_size的亲总数与行列正如事实从到S-1
- 我做小号平行区域使切片垂直于Y轴(与固定Ĵ号码)。我的意思是指数我对应x轴,j到y和k到z照常。
- 所以现在与从0到S-1个等级的每个进程负责P =(N + 1)/ s的在我的Y轴点:从秩* P到秩* p + p-1
- 现在我遇到了创建三个大小为[N + 1] [p] [N + 1]的阵列的问题。三,因为在每一步的计算我使用的值从前一个时间步和从“双前(先前的前)”(对不起,我不知道怎么说正确的:))
我试图这样做只是想:
for(int i = 0; i < N_p+1; i++) {
u[i] = new double*[N_p+1];
u_prev[i] = new double*[N_p+1];
u_prev_prev[i] = new double*[N_p+1];
for(int j = 0; j < N_p+1; j++) {
u[i][j] = new double[N_p+1];
u_prev[i][j] = new double[N_p+1];
u_prev_prev[i][j] = new double[N_p+1];
for(int k = 0; k < N_p+1; k++) {
u[i][j][k] = 0.0;
u_prev[i][j][k] = 0.0;
u_prev_prev[i][j][k] = 0.0;
}
}
}
但我的朋友谁已经做了这个任务告诉我将有问题,当我需要发送或收到消息/从其他进程(因为我需要发送完整的层大小为(N + 1)^ 2这些都是垂直于Y轴的,并且将这些阵列放置在内存中将会是一个大问题
同样我们并不需要全部N + 1点在Y轴上,正如我先做的那样,只是p其中每个过程都可以。由于内存问题是非常实际的(最大N在一些测试将在1536左右。我们给出了测试资源非常少)
于是,他提出了这样做的:(他垂直于X轴做并行片,而不是Y轴从我和记数到N-1和不从到ň作为我来说,这不是什么大问题,但是这个代码是某种魔术对我来说,我不明白它完全反正。)
float* buffer = new float[N * N * (N/s) * 3];
float ***u;
for (int i = left; i < right; ++i) {
u[i] = new float*[N];
for (int j = 0; j < N; ++j) {
u[i][j] = buffer + (i - left)*N*N + j*N;
}
}
所以我尝试在我的大脑着火时做类比,并且很快就会爆炸:
float* buffer = new float[(N+1) * p * (N+1) * 3];
float ***u;
for (int i = 0; i <= N; ++i) {
u[i] = new float*[p];
//p = right-left+1
for (int j = left; j <= right; ++j) {
u[i][j] = buffer + ???; //SOS
}
}
请有人试着理解这种方法,并解释什么来代替“???”。或者其他更好的解决方案。
而且我的队友告诉记者,这将是可以简单地写U [i] [j] [k]的代码但是我不知道我是否有ķ指数与这样definiton是否我需要改变我所有的计算语法。
对不起,有这么大的解释和问题。我真的不想自己理解它,并很快解决它。但现在我被卡住了。
同时粘贴一个立方体的小图像和红色的标记图层,用于一些简单的vizualization。
http://www.boost.org/doc/libs/1_61_0/libs/multi_array/doc/user。 html –
在你发布的第二个代码中,你没有足够的“层次”(不知道别的怎么说)。它应该是:
float ***u; u = new float**[N + 1];
等 –对于访问您的单维数组,假设您的大小是x = 2,y = 2和z = 2。访问变成:[(i * y * z)+(j * y) + k]。 –