Cuda 部分线程同步

Cuda 部分线程同步,cuda,Cuda,在我的应用程序中,我已经划分了工作,以便每个经纱做一个工作单元 为了在装置上开始工作,每个块的线程零必须计算从常数C0到CW的递归关系,其中W=#warp-1 从概念上看,它是这样的: if(threadId.x ==0) { for(x=1;x<#warps;x++) { C[x] = calc_recur(C[x-1]); } } syncthreads(); for(x=1;x<#warps;x++) { if(threadId.x =

在我的应用程序中,我已经划分了工作,以便每个经纱做一个工作单元

为了在装置上开始工作,每个块的线程零必须计算从常数
C0
CW
的递归关系,其中
W=#warp-1

从概念上看,它是这样的:

if(threadId.x ==0) {
    for(x=1;x<#warps;x++) {
        C[x] = calc_recur(C[x-1]);
    }
}
syncthreads();
for(x=1;x<#warps;x++) {
    if(threadId.x ==0) {
        C[x] = calc_recur(C[x-1]);
    }
    if(x < warpId) {
        partial_syncthreads(x);
    }
}
if(threadId.x==0){

对于(x=1;x,我不能完全确定,但我怀疑是否有办法减少内核运行时的线程数量

因此,我建议:

(1) 保持原样,同步线程在这一点上毫无意义

(2) 将内核拆分为多个内核。这样可以减少线程数来计算显示的代码。但使用此方法,您将无法访问共享内存


(3) 在主机上执行计算。由于这是一个高度串行的实现,这可能是更快的方法。在这里,您必须确保您的函数
calc_recur()
非常昂贵,传输到主机不会抵消速度的好处。

我不完全确定,但我怀疑是否有办法减少内核运行时的线程数量

因此,我建议:

(1) 保持原样,同步线程在这一点上毫无意义

(2) 将内核拆分为多个内核。这样可以减少线程数来计算显示的代码。但使用此方法,您将无法访问共享内存


(3) 在主机上执行计算。因为这是一个高度串行的实现,所以这可能是更快的方法。在这里,您必须确保您的函数
calc\u recur()
足够昂贵,传输到主机不会抵消速度优势。

首先:为什么要这样做?
syncthreads()
只确保所有线程都完成了它们以前的工作。我看不出为什么要在每个循环中同步它们。第二点:你可能会混合使用
block
warp
这两个术语吗?我为什么要这样做:如果可能,它会创建一个临时工作管道,允许warp开始他们的工作越早,它也会越早完成,但随后会被另一个工作填充。由于我在每个工作单元上的工作都大量使用随机访问,我请求访问许多cachline,因此为了更早地进行一些工作,可能会减轻内存总线的一些压力。我会同步每个循环的原因是s,这样它们就不能在计算其工作单位之前逃逸。不,小于x的扭曲中的线程已计算其工作单位。好的。我明白你的意思。不过,我认为你应该用“释放”之类的词替换术语“同步”(这只确保每个线程都在调用此函数的点上)。是什么阻止您停止内核,在一个小内核中计算
C[x]
,然后再次运行一个更大的内核(或者您下一步要做什么)?这将释放所有不需要的线程,直到您启动下一个内核。首先:为什么要这样做?
syncthreads()
只确保所有线程都完成了它们以前的工作。我看不出为什么要在每个循环中同步它们。第二点:你可能会混合使用
block
warp
这两个术语吗?我为什么要这样做:如果可能,它会创建一个临时工作管道,允许warp开始他们的工作越早,它也会越早完成,但随后会被另一个工作填充。由于我在每个工作单元上的工作都大量使用随机访问,我请求访问许多cachline,因此为了更早地进行一些工作,可能会减轻内存总线的一些压力。我会同步每个循环的原因是s,这样它们就不能在计算其工作单位之前逃逸。不,小于x的扭曲中的线程已计算其工作单位。好的。我明白你的意思。不过,我认为你应该用“释放”之类的词替换术语“同步”(这只确保每个线程都在调用此函数的点上)。是什么阻止您停止内核,在一个小内核中计算
C[x]
,然后再次运行一个更大的内核(或者您下一步要做什么)?这将释放所有不需要的线程,直到您启动下一个内核。