我有以下代码:
__global__ void interpolation(const double2* __restrict__ data, double2* __restrict__ result, const double* __restrict__ x, const double* __restrict__ y, const int N1, const int N2, int M)
{
int i = threadIdx.x + blockDim.x * blockIdx.x;
[...]
double phi_cap1, phi_cap2;
if(i<M) {
for(int m=0; m<(2*K+1); m++) {
[calculate phi_cap1];
for(int n=0; n<(2*K+1); n++) {
[calculate phi_cap2];
[calculate phi_cap=phi_cap1*phi_cap2];
[use phi_cap];
}
}
}
}
我想在 Kepler K20 卡上使用动态编程来调度处理phi_cap1
并phi_cap2
并行处理一堆线程,以减少计算时间。K=6
在我的代码中,所以我启动了一个13x13
线程块。
按照 CUDA 动态并行编程指南,我在全局内存中分配与子内核交换数据所需phi_cap
的169
元素矩阵(由 和 的乘积形成phi_cap1
)。确实,引用指南,phi_cap2
作为一般规则,传递给子内核的所有存储都应该从全局内存堆中显式分配。
然后我结束了以下代码
__global__ void interpolation(const double2* __restrict__ data, double2* __restrict__ result, const double* __restrict__ x, const double* __restrict__ y, const int N1, const int N2, int M)
{
int i = threadIdx.x + blockDim.x * blockIdx.x;
[...]
dim3 dimBlock(2*K+1,2*K+1); dim3 dimGrid(1,1);
if(i<M) {
double* phi_cap; cudaMalloc((void**)&phi_cap,sizeof(double)*(2*K+1)*(2*K+1));
child_kernel<<<dimGrid,dimBlock>>>(cc_diff1,cc_diff2,phi_cap);
for(int m=0; m<(2*K+1); m++) {
for(int n=0; n<(2*K+1); n++) {
[use phi_cap];
}
}
}
}
问题是第一个例程需要5ms
运行,而第二个例程,即使通过评论child_kernel
启动,也需要23ms
,几乎所有时间都花在cudaMalloc
API 上。
由于在动态编程中经常需要分配内存空间来与子内核交换数据,而唯一的解决方案似乎是全局内存占用了这么多时间,在我看来,动态编程有用性的一个严重瓶颈是数据交换,除非有办法规避全局内存分配问题。
那么问题是:对于上述问题是否有任何解决方法,即从内核中分配全局内存时需要花费这么多时间?. 谢谢
评论中提出的解决方案
从父内核外部分配所需的全局内存。我已经验证从父内核外部分配所需的全局内存要快得多。