如果我使用共享内存,可以分配多少块?

时间:2015-05-13 08:05:50

标签: c++ memory cuda

我是Cuda编程的新手。 我可以访问设备“Tesla K10”。 我正在处理复杂问题,每个问题实例需要大约20 KB的内存。 既然cuda提供了并行化,我决定每个块使用96个线程(记住warp)来解决问题的一个实例。 现在问题是我有非常大量的问题要解决(比如超过1,600,000)。 我知道这样大的内存需求甚至不适合全局内存(在我的情况下是3.5 GBytes,如下面的DeviceQuery输出中所示),所以我必须一次使用少量问题来解决。

另外,我已经为每个块映射了每个问题以解决问题的实例。

现在,我能够解决全局内存中数据的大量问题。但共享内存比全局快,所以我打算使用共享内存20 KB(每个问题)。

1)现在我的困惑是这将允许我一次只能解决共享内存中的2个问题(即40KBytes< 48KBytes的共享内存)。 (基于我对cuda的理解,如果我知道的话,请纠正我。)

2)如果我在内核中声明这个20 KB的数组是否意味着这个(20KBytes * number_of_blocks)将是共享内存使用? number_of_blocks 表示要解决的问题的数量。 我的启动配置是        问题<>>(...)

所有你在这方面的帮助都将得到高度认可。 提前感谢你。

***My partial Device Query***

Device : "Tesla K10.G1.8GB"
  CUDA Driver Version / Runtime Version          6.5 / 5.0
  CUDA Capability Major/Minor version number:    3.0
  Total amount of global memory:                 3584 MBytes (3757637632 bytes)
  ( 8) Multiprocessors, (192) CUDA Cores/MP:     1536 CUDA Cores
  GPU Clock rate:                                745 MHz (0.75 GHz)
  Memory Clock rate:                             524 Mhz
  Memory Bus Width:                              2048-bit
  L2 Cache Size:                                 4204060 bytes
  Maximum Texture Dimension Size (x,y,z)         1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096)
  Maximum Layered 1D Texture Size, (num) layers  1D=(16384), 2048 layers
  Maximum Layered 2D Texture Size, (num) layers  2D=(16384, 2046), 65536 layers
  Total amount of constant memory:               65536 bytes
  **Total amount of shared memory per block:       49152 bytes**
  Total number of registers available per block: 65536
  Warp size:                                     32
  Maximum number of threads per multiprocessor:  0
  Maximum number of threads per block:           1024
  Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
  Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)
  Maximum memory pitch:                          2147483647 bytes
...

1 个答案:

答案 0 :(得分:2)

首先,快速摘要检查我理解正确:

  • 你需要解决约1.5M的问题,这些问题是完全独立的,即令人尴尬的并行
  • 每个问题都有一个~20 KB
  • 的数据集

考虑到整个问题需要大于30 GB的内存,因此很明显您需要将这组问题分成几批。使用4 GB卡(约3.5 GB可用于ECC等),您可以随时处理大约150,000个问题。如果您要对这些进行双重缓冲,以允许通过计算当前批次来同时传输下一批,那么您需要批量查看75K问题(如果需要输出空间等,可能会更少)。 / p>

首先要考虑的是你是否可以并行化每个问题,即有没有办法为单个问题分配多个线程?如果是这样,那么你应该考虑分配一个线程块来解决个别问题,使用共享内存可能是值得考虑的,尽管你会限制每个SM占用两个块,这可能会影响性能。

如果你无法在问题中进行并行化,那么你不应该考虑共享内存,因为正如你所说,你将限制自己每个SM的两个线程(从根本上消除了GPU计算的好处)。相反,您需要确保全局内存中的数据布局能够实现合并访问 - 这很可能意味着使用SoA(数组结构)布局而不是AoS(结构数组)。

你的第二个问题有点令人困惑,不清楚你的意思是"阻止"在GPU上下文或问题上下文中。但是从根本上说,如果在内核代码中声明一个20 KB的__shared__数组,则每个数据块将分配一次,每个数据块将具有相同的基地址。

更新OP的评论

GPU包含许多SM,每个SM都有一个小的物理内存,用于L1和共享内存。在您的情况下,K10,每个SM有48 KB可用作共享内存,这意味着任何时候SM上的所有块执行在它们之间最多可以使用48 KB。由于每个块需要20 KB,因此您可以随时在SM上执行最多两个块。这不会影响您可以在启动配置中设置的块数,它只会影响它们的计划方式。 This answer更详细地讨论(虽然对于每个SM有16 KB的设备)和this (very old) answer稍微解释一下,尽管可能是最有帮助的(并且是最新的)信息CUDA education pages