C++ 提高三维阵列的性能
我试着在巨大的3D结构阵列中循环,但它运行得太慢了。 然后我用1D数组代替3D数组,但没有成功 我使用下面的结构来描述一个3D网格单元的参数:C++ 提高三维阵列的性能,c++,performance,bigdata,C++,Performance,Bigdata,我试着在巨大的3D结构阵列中循环,但它运行得太慢了。 然后我用1D数组代替3D数组,但没有成功 我使用下面的结构来描述一个3D网格单元的参数: struct cellStruct { double v1; // more variables here double v15; double v16; double v17; double v18; }; 请看两种常用的方法 三维阵列 #define Nx 500 #define Ny 500 #de
struct cellStruct
{
double v1;
// more variables here
double v15;
double v16;
double v17;
double v18;
};
请看两种常用的方法
#define Nx 500
#define Ny 500
#define Nz 500
cellStruct ***cell;
cell = new cellStruct **[Nx];
for(int i=0;i<Nx;i++)
{
cell[i]=new cellStruct *[Ny];
for(int j=0;j<Ny;j++)
cell[i][j]=new cellStruct [Nz];
}
for (i = 0; i< Nx; ++i)
for (j = 0; j< Ny; ++j)
for (k = 0; k< Nz; ++k)
{
// big algorithm that uses array like in string below
cell[i][j][k+1].v1 = cell[i][j+1][k-1].v2 *
cell[i+1][Ny-1][k+1].v5;
}
井500^3相当大->125M单元
- 因此,静态分配是不可能的
- 每个double都是8字节,因此对于8B x 125M内的每个double,它的值都是1G字节(在本例中,G是1000^3,而不是1024^3!!!)
- 因此,单元内的每个双变量约为1GB
- 那么,定义n[GB]数据处理的慢运行时间意味着什么
- 所以计算出的数据至少适合一级缓存
- 这意味着要分块计算所有数据
- 当然,如果你没有重复使用细胞,那么你没有什么可以改进的
- 尽量使你的计算并行化
- 但是你的数据太大了,所以这种方法甚至会减慢速度,所以要小心强>
- 当您的数据不适合缓存时,您的计算能力就像更强大的386机器强>
- 对您来说,最好的选择是一些单元格打包算法
- 它们是不是体素的
- 因此相邻单元应相似(区域内)
- 我强烈推荐RLE(运行长度编码)
- 对于这类数据,它是快速且非常有效的(至少对于我假设您使用的数据)
- 如果您的数据不适合RLE,则将单元格划分为多个区域,并使用DCT/iDCT(如jpg压缩)
- 打包/解包数据将大大缩短计算时间
- 因为打包后的数据集可能会非常非常小
struct cellStruct
{
double* v1; // you can use std::vector<double> instead of double*
// more variables here
double* v15;
double* v16;
double* v17;
double* v18;
};
如果您的大小都是预处理器定义,那么您最好声明
cellStruct[Nx][Ny][Nz]
。另外,请注意,在第一个示例中,您的程序可能会因为(k=0;k)的而崩溃。这可能会提高性能。此外,当您的结构单元只包含双精度时,您也可以尝试将其编写为数组,以便单元[i][j+1][k-1]。v2
变成单元[i][j+1][k-1][2]
,也许这有更大的优化潜力…最近有助于解决类似的性能问题,因此请查看我的答案以获取见解。切换到浮动时,处理数据会减半,因此bullet 3更适合您。另外,指针魔术不会为您带来任何有用的效果
struct cells
{
double ***v1;
// ...
double ***v15;
double ***v16;
double ***v17;
double ***v18;
};
struct cellStruct
{
double* v1; // you can use std::vector<double> instead of double*
// more variables here
double* v15;
double* v16;
double* v17;
double* v18;
};
#define CELL_ACCESS(cells,vn,i,j,k) (cells.vn[(i)*Ny*Nz + (j)*Ny + (k)])
cellStruct cells;
cells.v1 = new double[Nx*Ny*Nz]; // if you use std::vector, adjust code accordingly
cells.v2 = new double[Nx*Ny*Nz];
...
for (i = 1; i< Nx-1; ++i)
for (j = 1; j< Ny-1; ++j)
for (k = 1; k< Nz-1; ++k)
{
CELL_ACCESS( cells, v1, i, j, k+1) =
CELL_ACCESS( cells, v2, i, j+1, k-1) *
CELL_ACCESS( cells, v5, i+1, Ny-1, k+1);
}