【问题标题】:How slow is comparison and branching on GPUGPU上的比较和分支有多慢
【发布时间】:2014-06-20 07:11:15
【问题描述】:

我读到 GPU 上的比较和分支很慢。我想知道多少钱。 (我对 OpenCL 比较熟悉,但这个问题对于 CUDA、AMP 也很普遍……)

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

例如这样的代码(注意:此示例代码尚未针对 GPU 进行优化以提高可读性...因此分区到工作组,本地内存的预传...缺失)

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] ...
     }
} }
  • 尽管有很多if 分支和 比较? (即,如果每个元素的 4-5 次比较比 CPU 上相同的 4-5 次比较慢 10 倍,这将是一个瓶颈)
  • 是否有任何优化技巧如何最小化if 分支和比较变慢了?

我在这个液压腐蚀代码中使用的: http://www.openprocessing.org/sketch/146982

【问题讨论】:

  • 我建议您查看@talonmies 对问题Is Branch Divergence Really So Bad? 的评论,它有效地总结了问题点。
  • 对于你的情况,继续,ifs 并没有真正转移这么多。

标签: cuda opencl gpgpu


【解决方案1】:

如果您需要进行比较并且数组长度“n”真的很大,那么您可以使用归约而不是顺序比较。减少将在 O (log n) 时间内并行进行比较,而不是按顺序进行时 O (n)。

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

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

【讨论】:

  • 嗨,是的,正如我试图在这里解释的那样( NOTE: this code is just java, it is not yet optimized for GPU ) 我知道内存管理(全局/本地内存、工作组、磁贴......)我只是没有写在这里代码更具可读性。在这里,我想真正关注每个元素 4-5 次比较相对于普通卷积中 4-5 次浮点运算的成本
【解决方案2】:

分支本身并不慢。分歧是什么让你。 GPU 在“扭曲”或“波前”中以锁定步长计算多个工作项(典型值 16 或 32),如果不同的工作项采用不同的路径,它们都采用所有路径,但门写入基于它们所在的路径(使用谓词标志))。因此,如果您的工作项目总是(或大部分)以相同的方式分支,那么您很好。如果他们不这样做,惩罚可能会剥夺性能。

【讨论】:

  • 好的,所以在实践中,在我的例子中,if( dh&lt;dhmin ){ imin = -1; jmin = 0; dhmin = dh; } 会因为这个divergence 而受到惩罚,或者是否有可能以某种方式以矢量化方式进行评估(我的意思是所有 4 个案例在一个 @987654323 @)。或者是否有可能以某种方式重写为wavefronts 友好?
猜你喜欢
  • 2019-04-18
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
  • 2010-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多