【问题标题】:OpenCL global work-offset implies performance hit?OpenCL 全局工作偏移量是否意味着性能下降?
【发布时间】:2012-08-30 01:21:04
【问题描述】:

我有一个处理大图像的内核(OpenCL 1.1,数据类型是 image2d_t)。有时我只想处理这个图像的一个区域。显而易见的解决方案是使用全局工作偏移。我希望这会带来性能提升,但到目前为止,我只得到更差非零偏移的执行时间!

// Image is 4096x4096 pixels. Local work size is 8x8.
//
// Example A:
globalWorkSize = { 4096, 4096 };
globalWorkOffset = { 0, 0 };
// Execution time is 38 seconds
//    
// Example B:
globalWorkSize = { 3296, 3296 };
globalWorkOffset = { 400, 400 };
// Execution time is 58 seconds <------------------ ?!
//
// Example C: Cropped image @ 3296x3296 pixels
globalWorkSize = { 3296, 3296 };
globalWorkOffset = { 0, 0 };
// Execution time is 28 seconds

有人能解释一下为什么我会得到这些结果吗?

【问题讨论】:

  • 我们能看到你的内核吗(不一定是所有的内核,而是输入、输出、带有循环的一般结构等......)?这里没有什么可做的。
  • 我将尝试制作一个演示问题的最小示例。
  • 您是否尝试过将偏移量对齐到 64?任何未对齐的东西都会影响 GPU 性能。
  • 非常有趣!会试试的。
  • 你可以访问 CL 内核的程序集吗?

标签: performance opencl


【解决方案1】:

Lubo Antonov 关于数据访问对齐对性能很重要的观点是正确的。但另一个参数是以跨步模式访问内存。

从 x=400 和 y=400 开始的示例是:

. = item
x = work item
c = memory channel
stride = 4096 between y_item=1 and y_item=2 and in this stride, 
some of memory channels are left in "." areas and unused

  unused channel
  ^
  | 
  c c c c c c c c c c
  . . . . . . . . . . 
  . x x x x x x x x x
  . x x x x x x x x x
  . x x x x x x x x x
  . x x x x x x x x x
  . x x x x x x x x x
  . x x x x x x x x x
  . x x x x x x x x x
  . x x x x x x x x x
  . x x x x x x x x x

当然,前 400 个未使用的像素中有更多通道,但其中一些通道​​的数量少于“x”工作区域中的其他通道。例如,通道 2,3,4,5,6,7 在 "x" 中被访问了 20 次,但通道 1 被访问了 25 次,这会强制对它进行比其他通道更序列化的访问。

如果跨步区域的内存通道数与非跨步区域不同,则高 2 次方跨步内存访问使用较少的内存通道/存储库并降低性能。


硬件对性能的 Z 排序支持的优势也可能在工作区的左边缘被破坏。


如果每个扫描线不是 gpu 中计算单元数量的精确倍数,则同一计算单元可能无法从 L1 缓存中的最后一个扫描线获取缓存数据(请记住 Z 排序访问和邻居访问,例如高斯过滤器)

   c = compute unit, S=selected compute unit for observation
   kernel is accessing neighbour pixels too, for filtering, for example

   gpu has 10 compute units   

   strided: L1 cache not hit
   ..........
   .cccSccccc
   .ccccScccc
   .cccccSccc
   .ccccccScc
   .cccccccSc
   .ccccccccS

   non-strided: pixel[y-1] is already in L1, cache hit, more performance
   ..........
   cccScccccc
   cccScccccc
   cccScccccc
   cccScccccc
   cccScccccc

但这并不能保证,只是一个关于工作项的本能是为了最大核心占用而分配的,其中 gpu 的每个核心通过迭代工作分配平均加载,而不是这样:先填充,然后填充第二个,然后填充第三个,等等....填充第一个核心将有利于该核心效率,但让其他核心空置将破坏拥有更多核心恕我直言的优势。这也需要一个远程过滤内核。 5x5 过滤器将仅受益于边缘像素,而 51x51 过滤器将包括多个工作组。

【讨论】:

    【解决方案2】:

    虽然使用图像似乎是正确的选择,但可能并非总是如此。

    如果您不需要在像素之间进行插值并且不需要处理边框颜色,那么在图像上使用缓冲区可能会更好。

    即使您需要处理边界颜色,您也可以使用单独的内核来处理边缘区域和缓冲区,这可能会提供良好的整体性能。

    图像获得更好性能的原因在于能够从内存中一次加载多个像素,在某些架构中,指令一次可以加载 128 位。

    说到实际问题, 我的猜测是 hw 确实使用偏移量和工作 ID 计算每个像素的实际坐标。

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 2022-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      相关资源
      最近更新 更多