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]
,然后再次运行一个更大的内核(或者您下一步要做什么)?这将释放所有不需要的线程,直到您启动下一个内核。