拆分大CUDA内核并使用动态并行的好处

拆分大CUDA内核并使用动态并行的好处,cuda,Cuda,我有一个大内核,其中初始状态是使用不同的技术演化而来的。也就是说,我在内核中有一个循环,在这个循环中,对当前状态计算某个谓词,并根据该谓词的结果执行某个操作 内核需要一些临时数据和共享内存,但由于它很大,它使用了63个寄存器,占用率非常低 我想把内核分成许多小内核,但是每个块都是完全独立的,我(想我)不能在主机代码上使用一个线程来启动多个小内核 我不确定流是否适合这类工作,我从未使用过它们,但由于我可以选择使用动态并行,我想知道这是否是实现这类工作的一个好选择。 从内核启动内核快吗? 我是否需要

我有一个大内核,其中初始状态是使用不同的技术演化而来的。也就是说,我在内核中有一个循环,在这个循环中,对当前状态计算某个谓词,并根据该谓词的结果执行某个操作

内核需要一些临时数据和共享内存,但由于它很大,它使用了63个寄存器,占用率非常低

我想把内核分成许多小内核,但是每个块都是完全独立的,我(想我)不能在主机代码上使用一个线程来启动多个小内核

我不确定流是否适合这类工作,我从未使用过它们,但由于我可以选择使用动态并行,我想知道这是否是实现这类工作的一个好选择。 从内核启动内核快吗? 我是否需要复制全局内存中的数据以使其可用于子内核

如果我将我的大内核拆分为许多小内核,并在第一个内核中留下一个主循环,在必要时调用所需的内核(这允许我在每个子内核中移动临时变量),会帮助我增加占用率吗

我知道这是一个有点普通的问题,但我不知道这项技术,我想知道它是否适合我的情况,或者流是否更好

编辑: 为了提供一些其他细节,您可以想象我的内核具有这种结构:

__global__ void kernel(int *sampleData, int *initialData) {
    __shared__ int systemState[N];
    __shared__ int someTemp[N * 3];
    __shared__ int time;
    int tid = ...;
    systemState[tid] = initialData[tid];

    while (time < TIME_END) {
        bool c = calc_something(systemState);
        if (c)
            break;
        someTemp[tid] = do_something(systemState);
        c = do_check(someTemp);
        if (__syncthreads_or(c))
            break;
        sample(sampleData, systemState);
        if (__syncthreads_and(...)) {
            do_something(systemState);
            sync();
            time += some_increment(systemState);
        }
        else {
            calcNewTemp(someTemp, systemState);
            sync();
            do_something_else(someTemp, systemState);
            time += some_other_increment(someTemp, systemState);
        }
    }
    do_some_stats();
}
\uuuuu全局\uuuuuu无效内核(int*sampleData,int*initialData){
__共享的系统状态[N];
__共享_uuu_uuuint someTemp[N*3];
__共享时间;
int-tid=。。。;
systemState[tid]=初始数据[tid];
while(时间<时间\结束){
bool c=计算某物(系统状态);
如果(c)
打破
someTemp[tid]=做某事(systemState);
c=进行检查(某些温度);
如果(uuu或(c))
打破
样本(样本数据、系统状态);
如果(uu和(…)){
做某事(系统状态);
sync();
时间+=某些增量(系统状态);
}
否则{
calcNewTemp(某些温度,系统状态);
sync();
做其他事情(someTemp、systemState);
时间+=一些其他增量(一些温度、系统状态);
}
}
你有什么统计数据吗;
}
这是为了向您展示有一个主循环,有一些临时数据在某处使用,而不是在其他点中使用,有共享数据、同步点等等

线程用于计算矢量数据,而理想情况下,每个块中只有一个循环(当然,这不是真的,但逻辑上是真的)。。。每个区块有一个“大流量”

现在,我不确定在这种情况下如何使用流。。。“大循环”在哪里?我猜是在主机上。。。但是我如何协调,从一个循环,所有的块?这就是我最怀疑的地方。我可以使用来自不同主机线程(每个块一个线程)的流吗


我不太怀疑动态并行性,因为我可以轻松地保持大循环运行,但我不确定我在这里是否有优势。

我从动态并行性中受益,解决了以下形式的插值问题:

int i = threadIdx.x + blockDim.x * blockIdx.x;

for(int m=0; m<(2*K+1); m++) {

    PP1 = calculate_PP1(i,m);
    phi_cap1 = calculate_phi_cap1(i,m);  

        for(int n=0; n<(2*K+1); n++) {

            PP2 = calculate_PP2(i,m);
            phi_cap2 = calculate_phi_cap2(i,n);

            atomicAdd(&result[PP1][PP2],data[i]*phi_cap1*phi_cap2); } } }
inti=threadIdx.x+blockDim.x*blockIdx.x;

对于(int m=0;我想说流很适合解决你的问题。但是如果你热衷于尝试动态并行,那就去吧。我仍然在寻找一个能够提供加速的应用程序。谢谢,@tera。你有关于在这种情况下使用流的好资源吗?我对C编程指南了解不多,我是仍然不确定如何使用它们。我现在将在问题中添加一些关于内核结构的其他信息。谢谢,这是一个有用的答案。您能告诉我使用D.P.是否会增加占用率和/或减少寄存器使用率吗?我不认为动态并行性会减少寄存器使用率,但我认为它会增加。相反,我认为动态并行可以提高占用率。当然,一般性陈述是困难的,因为情况可能会随着情况的变化而变化。我只想说,在我的例子中,好处来自于我添加了一个新的并行级别。在原始代码中,
phi_cap1
phi_cap2
I的计算每个线程都是顺序的。使用动态并行,它会变得并行。好吧,很有趣。我希望有时间测试动态并行选项,看看它是否有助于占用率的增加,这是我现在的主要目标。谢谢,从父线程到子线程传递数据的唯一方法是通过全局内存?因为它是真实的y slow我不明白动态并行在这样的环境下有多有用handicap@elect在我开发的代码中,我设法在父内核之外预先分配我所需要的一切,而不是在父内核内部分配内存,以便与子内核交换数据。