Cuda GPU上的比较和分支有多慢

Cuda GPU上的比较和分支有多慢,cuda,opencl,gpgpu,Cuda,Opencl,Gpgpu,我读过GPU上的比较和分支很慢。我想知道多少钱。(我更熟悉OpenCL,但问题对CUDA来说也是一般性的,AMP…) 我想知道它,在我开始把我的代码移植到GPU之前。我特别感兴趣的是在2D数组中的每个点的邻域(4或9个最近邻域)中找到最小值。i、 类似于卷积,但我需要比较和分支,而不是求和和乘法 例如,类似这样的代码(注意:此示例代码尚未针对GPU的可读性进行优化,因此缺少分区到工作组、预取本地内存等功能) for(int i=1;i如果需要进行比较,并且数组长度'n'非常大,则可以使用缩减而不

我读过GPU上的比较和分支很慢。我想知道多少钱。(我更熟悉OpenCL,但问题对CUDA来说也是一般性的,AMP…)

我想知道它,在我开始把我的代码移植到GPU之前。我特别感兴趣的是在2D数组中的每个点的邻域(4或9个最近邻域)中找到最小值。i、 类似于卷积,但我需要比较和分支,而不是求和和乘法

例如,类似这样的代码(注意:此示例代码尚未针对GPU的可读性进行优化,因此缺少分区到工作组、预取本地内存等功能)


for(int i=1;i如果需要进行比较,并且数组长度'n'非常大,则可以使用缩减而不是顺序比较。缩减将在O(logn)时间内并行进行比较,而不是顺序进行时的O(n)

当您在GPU线程中按顺序访问内存时,内存访问是按顺序进行的,因为连续块是从同一个库访问的。相反,使用合并读取是很好的。您可以在这方面找到大量的示例


在GPU上,不要多次访问全局内存(因为GPU内存管理和缓存的工作方式与CPU不完全相同)。相反,应尽可能多地将全局内存元素缓存到线程的私有变量/共享内存中。

分支本身并不慢。发散是导致这种情况的原因。GPU计算多个工作项(典型16或32)在“扭曲”或“波前”的锁定步骤中,如果不同的工作项采用不同的路径,则它们都采用所有路径,但门写入基于它们所在的路径(使用谓词标志))。因此,如果您的工作项总是(或大部分)以相同的方式分支,那么您就是优秀的。如果他们不这样做的话,处罚可能会剥夺他们的表现

您好,是的,正如我试图在这里解释的那样
(注意:这段代码只是java,它还没有针对GPU进行优化)
我知道内存映像(全局/本地内存、工作组、平铺…)我只是在这里写它不是为了让代码更具可读性。在这里,我想真正关注的是每个元素相对于正常卷积中的4-5个浮点运算的4-5个比较的成本。我建议看一下@talonmies对问题的评论,它有效地总结了问题点。对于你的情况,继续,ifs并没有真正转移太多。好的,在实践中,在我的例子中,
if(dh
for(int i=1;i<n-1;i++){ for(int j=1;j<n-1;j++){ // iterate over 2D array
     float hij  = h[i][j];
     int imin = 0,jmin = 0;
     float dh,dhmin=0;
     // find lowest neighboring element h[i+imin][j+jmin] of h[i][j]
     dh = h[i-1][j  ]-hij;  if( dh<dhmin ){  imin = -1; jmin =  0; dhmin = dh; }
     dh = h[i+1][j  ]-hij;  if( dh<dhmin ){  imin = +1; jmin =  0; dhmin = dh; }
     dh = h[i  ][j-1]-hij;  if( dh<dhmin ){  imin =  0; jmin = -1; dhmin = dh; }
     dh = h[i  ][j+1]-hij;  if( dh<dhmin ){  imin =  0; jmin = +1; dhmin = dh; }
     if( dhmin<-0.00001 ){ // if lower
       // ... Do something with hij, dhmin and save to h[i+imin][j+jmin] ...
     }
} }