CUDA 并行化依赖的 2D 阵列
CUDA parallelizing a dependent 2D array
我有一个以下形式的示例循环。请注意,我的psi[i][j]
依赖于psi[i+1][j], psi[i-1][j], psi[i][j+1] and psi[i][j-1]
,我必须仅计算内部矩阵的psi
。现在我尝试在 CUDA 中编写它,但结果与顺序不同。
for(i=1;i<=leni-2;i++)
for(j=1;j<=lenj-2;j++){
psi[i][j]=(omega[i][j]*(dx*dx)*(dy*dy)+(psi[i+1][j]+psi[i-1][j])*(dy*dy)+(psi[i][j+1]+psi[i][j-1])*(dx*dx) )/(2.0*(dx*dx)+2.0*(dy*dy));
}
这是我的 CUDA 格式。
//KERNEL
__global__ void ComputePsi(double *psi, double *omega, int imax, int jmax)
{
int x = blockIdx.x;
int y = blockIdx.y;
int i = (jmax*x) + y;
double beta = 1;
double dx=(double)30/(imax-1);
double dy=(double)1/(jmax-1);
if((i)%jmax!=0 && (i+1)%jmax!=0 && i>=jmax && i<imax*jmax-jmax){
psi[i]=(omega[i]*(dx*dx)*(dy*dy)+(psi[i+jmax]+psi[i-jmax])*(dy*dy)+(psi[i+1]+psi[i-1])*(dx*dx) )/(2.0*(dx*dx)+2.0*(dy*dy));
}
}
//Code
cudaMalloc((void **) &dev_psi, leni*lenj*sizeof(double));
cudaMalloc((void **) &dev_omega, leni*lenj*sizeof(double));
cudaMemcpy(dev_psi, psi, leni*lenj*sizeof(double),cudaMemcpyHostToDevice);
cudaMemcpy(dev_omega, omega, leni*lenj*sizeof(double),cudaMemcpyHostToDevice);
dim3 grids(leni,lenj);
for(iterpsi=0;iterpsi<30;iterpsi++)
ComputePsi<<<grids,1>>>(dev_psi, dev_omega, leni, lenj);
其中psi[leni][lenj] and omega[leni][lenj]
和双精度数组。
问题是顺序的,CUDA 代码给出不同的结果。代码中是否需要任何修改?
您正在使用全局内存,并且正在更改 psi 条目,而其他线程可能需要旧值。只需将新迭代的值存储在单独的变量中即可。但请记住,您必须在每次迭代后交换变量!更复杂的方法是将共享内存和空间域分配给单独的线程的解决方案。只需谷歌搜索用于求解热/扩散方程的 CUDA 教程,您就会明白。
for(i=1;i<=leni-2;i++)
for(j=1;j<=lenj-2;j++){
psi[i][j]= ( omega[i][j]*(dx*dx)*(dy*dy) +
(psi[i+1][j]+psi[i-1][j]) * (dy*dy) +
(psi[i][j+1]+psi[i][j-1]) * (dx*dx)
)/(2.0*(dx*dx)+2.0*(dy*dy));
}
我认为这个内核的顺序也不正确:psi[i][j]
的值取决于此处操作的顺序 - 因此您将使用未更新的psi[i+1][j]
和psi[i][j+1]
,但psi[i-1][j]
和psi[i][j-1]
已在此扫描中更新。
确保使用 CUDA 的结果会有所不同,其中操作的顺序不同。
要强制执行这样的排序,如果可能的话,您需要插入如此多的同步,这对于 CUDA 来说可能不值得。这真的是你需要做的吗?
相关文章:
- 库特<<恩德尔;不适用于打印 2D 阵列
- 具有可变尺寸的 C++ 2D 阵列
- 如何遍历 2D 阵列?
- 超级对撞机2D阵列:生成嵌套:包装/尺寸问题
- 动态 2D 阵列.为什么分段错误?
- 尝试使用2D阵列
- 分配给阵列时出现分段错误?黑客排名 2D 阵列 - DS.
- 如何将1D阵列访问为2D阵列
- 分配/访问2d阵列,使得2d子块是连续的
- 重新分配2D阵列并删除旧阵列
- 不使用新的动态2D阵列
- 我正在为2D阵列参数而挣扎
- 特征和巨大的密集 2D 阵列
- 使用 std::transform 在 2d C 阵列上转换为 1d C 数组
- 解除分配此特定 2D 阵列的内存
- 使用两个不同大小的一维阵列制作 2D 阵列
- 返回C 中2D阵列的对角线元素总和
- 2D阵列让我卡住了
- 用pybind11铸造2D阵列
- 我的 2D 阵列无法读取文本文件并正确输出