【问题标题】:Why order of dimension makes big difference in performance?为什么维度顺序对性能有很大影响?
【发布时间】:2015-01-10 02:35:30
【问题描述】:

为了启动一个 CUDA 内核,我们使用dim3 来指定维度,我认为每个维度的含义是用户可以选择的,例如,它可以表示 (width, height) 或 (rows, cols) ,意思相反。

于是我对SDK中的CUDA示例做了一个实验:3_Imaging/convolutionSeparable,简单地在内核函数中交换.x和.y,并且反转用于启动内核的块和线程的维度,所以含义发生了变化从 dim(width, height)/idx(x, y) 到 dim(rows, cols)/idx(row, col)。

结果是一样的,但是性能下降了,在我的机器(SM 3.0)上,原来的大约需要26ms,而修改后的大约需要40ms。

我的问题是,有什么不同? (rows, cols) 对 CUDA 不可行吗?

附:我只修改convolutionRows,没有convolutionColumns

编辑:可以在here找到更改。

【问题讨论】:

  • 你的内核启动配置是什么?
  • @kronos,它们被转置了,例如dim3(a, b) 变为 dim3(b, a)。
  • 我对引用的代码不熟悉,但是一般来说这种线程块配置转置是和内存子系统交互的,因为多维线程块是通过特定的方式映射到全局线程索引的.通常,您希望 x 维度中的单位步长与数组元素中的单位步长相对应,以获得最佳性能。我建议使用分析器检查共享和全局内存事件,以深入了解您的特定案例的两种变体。
  • @Jamboree,是的,我从你的问题中得到了这个,但实际数字如何?例如:32x8 将(通常)产生比 8x32 更好的内存访问模式,因为 warp 中的所有线程都将访问合并的全局内存。
  • 在更改前后提供您的代码会非常有用,因为就问题而言,我们只能猜测。

标签: cuda parallel-processing


【解决方案1】:

您的更改至少有两个潜在后果:

  1. 首先,您将 内存访问模式 更改为主内存,因此 访问与原始情况一样没有合并。

    您应该以与以往相同的方式考虑 GPU 主内存 “CPU”内存,即预取、阻塞、顺序访问…… 应用技术以获得性能。

    如果您想了解有关此主题的更多信息,则必须阅读 这张纸。 What every programmer should know about memory。 你会发现一个例子,一个行和列专业之间的比较 在那里访问矩阵的元素。

    要了解和了解这有多重要,请考虑大多数情况 - 如果不是 all-GPU 高性能代码执行矩阵转置 在任何计算之前以实现更合并的内存 访问,而且这个额外的步骤仍然值得 表现。 (例如稀疏矩阵运算)

  2. 第二。这更微妙,但在某些情况下,它对内核的性能有很深的影响;启动配置。启动 20 个 10 个线程的块与启动 10 个 20 个线程的块是不一样的。 线程需要的资源量(共享内存、寄存器数量...)存在很大差异。线程需要的资源越多,可以在单个 SM 上映射的扭曲越少,因此占用率越低……并且在大多数情况下,性能越低。 这不适用于您的问题,因为块数等于线程数。

在为 GPU 编程时,您必须了解架构,以便了解这些更改将如何改变性能。当然,我对代码不熟悉,所以这两者之间会有其他因素。

【讨论】:

  • 内存访问模式是问题所在,这里第 2 点不是问题,因为配置大小相同。
  • 你完全正确。我将更改答案以指定这一点。
猜你喜欢
  • 2012-05-11
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 2012-09-01
  • 2012-04-13
相关资源
最近更新 更多