我是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
...
答案 0 :(得分:2)
首先,快速摘要检查我理解正确:
考虑到整个问题需要大于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