0

任何人都可以帮助使用 MPI 展平 3D 数组的一般格式吗?我想我可以通过使用 (i+xlength*j+xlength*ylength*k) 来获得一维数组,但是我在使用引用数组特定单元格的方程时遇到了麻烦。

我尝试根据我拥有的处理器数量将代码分块,但是当我需要另一个处理器具有的值时,我很难过。有没有办法使用幽灵单元或指针杂耍使这更容易(和更有效)?

4

1 回答 1

2

你至少有两个选择。更简单的一种是声明一个预处理器宏来隐藏索引计算的复杂性,例如:

#define ARR(A,i,j,k) A[(i)*ylength*zlength+(j)*zlength+(k)]

ARR(myarray,i,j,k) = ARR(myarray,i+1,j,k) + ARR(myarray,i,j+1,k) + ...

这很笨拙,因为宏只能处理固定前导维度的数组,例如 x ylengthx zlength

更好的方法是使用所谓的涂料向量。涂料向量基本上是大数组的索引。您分配一个大的扁平块xlength * ylength * zlength来保存实际数据,然后创建一个索引向量(在 3D 情况下实际上是一棵树)。在您的情况下,索引有两个级别:

  • 顶层,由xlength指向
  • 第二层,由xlength指针数组组成,每个指针都包含ylength指向zlength内存中元素块开头的指针。

我们称之为顶级指针数组A。然后A[i]是一个指针数组,该指针数组描述了i第 -th 块数据。A[i][j]是第 -th 指针数组的第j-th 个元素i,它指向data[i][j][0](如果data是 3D 数组)。涂料向量的构建与此类似:

double *data = new double[xlength*ylength*zlength];
double ***A;

A = new double**[xlength];
for (int i = 0; i < xlength; i++)
{
   A[i] = new double*[ylength];
   for (int j = 0; j < ylength; j++)
      A[i][j] = data + i*ylength*zlength + j*zlength;
}

涂料向量与普通数组一样易于使用,但有一些特殊考虑。例如,A[i][j][k]将允许您访问所需的data. 对涂料向量的一个警告是,顶层由指向其他指针表的指针组成,而不是指向数据本身的指针,因此A不能用作 的快捷方式&A[0][0][0],也不能A[i]用作 的快捷方式&A[i][0][0]。仍然A[i][j]相当于&A[i][j][0]。另一个需要注意的是,这种形式的数组索引比普通的 3D 数组索引慢,因为它涉及指针追逐。

有些人倾向于为数据和涂料向量分配一个存储块。他们只是将索引放在分配块的开头,然后实际数据在后面。这种方法的优点是处理数组就像删除整个内存块一样简单,而处理使用上一节中的代码创建的涂料向量需要多次调用free运算符。

于 2013-04-29T23:11:24.767 回答