我发现NVIDIA Tesla M2050的共享内存速度并没有提高 每块大约49K共享内存。实际上,如果我分配 共享内存中的一个大型char数组会降低我的程序速度。例如
__shared__ char database[49000];
给我的运行时间比
慢__shared__ char database[4900];
程序只访问数据库的前100个字符,因此需要额外的空间 没必要。我无法弄清楚为什么会这样。任何帮助,将不胜感激。 感谢。
答案 0 :(得分:30)
使用较大阵列时CUDA共享内存性能相对较差的原因可能与每个多处理器的可用共享内存数量有限有关。
每个多处理器托管多个处理器;对于现代设备,通常为32,经线中的线程数。这意味着,在没有分歧或内存停顿的情况下,平均处理速率为每个周期32条指令(由于流水线操作,延迟很高)。
CUDA为多处理器安排了几个块。每个块由几个经线组成。当warp在全局内存访问上停止(即使合并的访问具有高延迟),也会处理其他warp。这有效地隐藏了延迟,这就是GPU中可接受高延迟全局内存的原因。为了有效地隐藏延迟,您需要执行足够的额外warp,直到停止的warp可以继续。如果所有warp在内存访问中停止,则无法再隐藏延迟。
共享内存分配给CUDA中的块,并存储在GPU设备上的单个多处理器上。每个多处理器都有一个相对较小的固定数量的共享内存空间。与多处理器在共享内存和寄存器使用方面可支持的相比,CUDA无法为多处理器安排更多块。换句话说,如果多处理器上的共享内存量是X并且每个块都需要Y共享内存,那么CUDA将一次安排不超过底层(X / Y)块到每个多处理器(它可能会更少,因为有其他约束,例如寄存器使用)。
因为,通过增加块的共享内存使用量,您可能会减少内核的活动warp数量 - 占用率,从而影响性能。您应该通过使用-Xptxas =“ - v”标志进行编译来查看内核代码;这应该给你注册和共享&每个内核的常量内存使用情况。在最新版本的CUDA占用率计算器中使用此数据和内核启动参数以及其他所需信息,以确定您是否可能会受到占用的影响。
编辑:
要解决问题的其他部分,假设没有共享内存库冲突和完全合并全局内存访问......这个答案有两个方面:延迟和带宽。共享内存的延迟将低于全局内存的延迟,因为共享内存在片上。带宽将大致相同。因此,如果您能够通过合并隐藏全局内存访问延迟,则不会受到惩罚(注意:访问模式在这里非常重要,因为共享内存允许可能更多样化的访问模式,几乎没有性能损失,因此可以即使您可以隐藏所有全局内存延迟,也可以使用共享内存。)
答案 1 :(得分:2)
此外,如果你增加每块的共享内存,CUDA将调度具有较少并发块的网格,因此它们都有足够的共享内存,因此它减少了并行性并增加了执行时间。
答案 2 :(得分:1)
gpu上可用的资源量有限。并发运行的块数大致与每个块的共享内存大小成反比。
这解释了当您启动使用大量共享内存的内核时运行时速度较慢的原因。