2013-03-24 49 views
1

我实现使用CUDA库尖峰神经网络,并感到非常不确定如何针对以下几点着手:我应该如何分配内存给许多(1000+)我不知道大小的数组?

  1. 分配内存(cudaMalloc)到许多不同的阵列。到目前为止,只需使用cudaMalloc'手动'就足够了,因为我不必制作超过10个左右的阵列。但是,我现在需要指出并为数千个数组分配内存。

  2. 如何确定分配给每个阵列的内存量。阵列的高度为3(突触后神经元id为1行,突触后神经元突触数量为1行,突触功效为1行),但它们具有不确定的长度随时间变化随着传出突触的数量。

听说在CUDA动态存储器分配是很慢的,并与分配对于每个阵列所需的最大存储器的想法,以便玩弄,然而每神经传出突触的数量从100-10,000且因此改变我认为这是不可行的,因为我已经有了1000个神经元。

如果任何人都可以告诉我如何分配内存到GPU上的许多阵列,和/或如何编码上述任务的快速动态内存分配,我将不会非常感激。

在此先感谢!

+0

你有什么理由不能只用一个大的内存分配来代替许多小内存? – talonmies 2013-03-24 17:55:14

+0

我打算使用很多小分配的原因是我希望信息的“结构”与邻接列表相似,也就是说,网络中的每个节点都有一个列表,告诉你它是哪个其他节点连接到(除了在我的情况下,它将是一个'矩阵',因为我有3行信息每个节点) - 我认为这将避免有许多零元素,如果我使用一个大型的3D数组。我是否认为这些零元素会耗尽内存? – Boyentenbi 2013-03-24 18:40:56

+0

只有两种选择:使用可用的分配器(例如设备上的cudaMalloc或malloc)或创建您自己的分配器。如果你担心速度,并且有很多小的分配,那么创建你自己的分配器可能是一条可行的路。这将涉及发布'cudaMalloc'一次或少数次,然后根据需要通过指针索引分配到设备上的分配区域。一个大的3D阵列可以简化编码,但有可能浪费更多的空间。智能分配器只会剥离尽可能多的空间。 – 2013-03-24 21:16:18

回答

1

如果您确实想要这样做,您可以根据需要多次拨打cudaMalloc;但是,这可能不是一个好主意。相反,试图找出如何布局内存,以便块中的相邻线程尽可能访问RAM的相邻元素。

这可能是有问题的原因是线程一次执行32个组(一个warp)。 NVidia的内存控制器非常聪明,所以如果相邻的线程要求RAM的相邻字节,它会将这些负载合并为一个可以高效执行的单个请求。相反,如果warp中的每个线程访问一个随机存储器位置,则整个warp必须等到32个内存请求完成。此外,对卡的内存的读写操作一次发生在整个缓存行中,因此如果线程不使用在从缓存中逐出之前读取的所有RAM,则会浪费内存带宽。如果不针对线程块内的连贯内存访问进行优化,则预计会有10倍至100倍的减速。

(边注意:以上的讨论仍然适用与后G80卡;第一代CUDA硬件(G80)甚至挑剔它也需要对齐的内存请求,如果程序员希望的凝聚行为)

相关问题