次のコードがあります。
__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 Dynamic Parallelism Programming Guide に従って、データを子カーネルと交換するために必要な要素の行列 ( と の積によって形成される) を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];
}
}
}
}
問題は、最初のルーチンの実行に時間がかかることですが、2 番目のルーチンは、起動に5ms
コメントを付けても、ほぼすべての時間がAPI に費やされます。child_kernel
23ms
cudaMalloc
動的プログラミングでは、子カーネルとデータを交換するためにメモリ空間を割り当てる必要があることが多く、唯一の解決策は非常に時間がかかるグローバルメモリであるように思われるため、動的プログラミングの有用性の深刻なボトルネックの1つはデータであると私には思えますグローバルメモリ割り当ての問題を回避する方法がない限り、交換してください。
問題は、上記の問題、つまり、カーネル内からグローバル メモリを割り当てるときに非常に時間がかかるという問題に対する回避策はありますか? . ありがとう
コメントで提案された解決策
親カーネルの外部から必要なグローバル メモリを割り当てます。親カーネルの外部から必要なグローバル メモリを割り当てる方がはるかに高速であることを確認しました。