我应该如何为我不知道大小的许多(1000+)数组分配内存?
Posted
技术标签:
【中文标题】我应该如何为我不知道大小的许多(1000+)数组分配内存?【英文标题】:How should I allocate memory to many (1000+) arrays which I don't know the size of? 【发布时间】:2013-03-14 04:05:04 【问题描述】:我正在使用 CUDA 库实现一个尖峰神经网络,我真的不确定如何处理以下事情:
将内存 (cudaMalloc) 分配给许多不同的数组。到目前为止,只需“手动”使用 cudaMalloc 就足够了,因为我不必制作超过 10 个左右的数组。但是,我现在需要为数千个数组创建指针并为其分配内存。
如何决定为每个数组分配多少内存。阵列的高度为 3(1 行用于突触后神经元 ID,1 行用于突触后神经元上的突触数量,1 行用于突触的功效),但它们的长度不确定,会随时间变化与传出突触的数量。
我听说 CUDA 中的动态内存分配非常慢,所以想为每个数组分配所需的最大内存,但是每个神经元的输出突触数量从 100 到 10,000 不等,所以我认为这是不可行,因为我有大约 1000 个神经元。
如果有人能建议我如何为 GPU 上的许多数组分配内存,和/或如何为上述任务编写快速动态内存分配代码,我将不胜感激。
提前致谢!
【问题讨论】:
你有什么理由不能只使用一个大内存分配而不是许多小的内存分配? 我打算使用许多小分配的原因是我希望信息的“结构”类似于邻接列表,即网络中的每个节点都有一个列表告诉您它连接到哪些其他节点(在我的情况下它将是一个“矩阵”,因为我每个节点有 3 行信息) - 我认为这将避免有许多零元素,如果我使用大型 3D 阵列。我是否认为这些零元素会耗尽内存? 只有两种选择:使用可用的分配器(例如 cudaMalloc,或设备上的 malloc)或创建自己的分配器。如果您担心速度,并且有很多小分配,那么创建自己的分配器可能是要走的路。这将涉及发出cudaMalloc
一次或少量次,然后根据需要通过指针索引到设备上的分配区域来分割碎片。大型 3D 阵列会简化编码,但可能会浪费更多空间。智能分配器只会剥离所需的空间。
此外,如果您有 1000 个数组,每个数组约 1000 字节,那么在当今具有 1GB 或 RAM 或更多的设备的大图中,这只有 1 MB。如果您的整体尺寸很小,请务必浪费空间并通过将每个元素设置为最大尺寸来保持代码简单(固定大小的分配器,或仅使用单个 3D 数组方法)。
【参考方案1】:
如果你真的想这样做,你可以拨打cudaMalloc
任意多次;但是,这可能不是一个好主意。相反,请尝试弄清楚如何布局内存,以便块中的相邻线程尽可能访问 RAM 的相邻元素。
这可能有问题的原因是线程一次以 32 个为一组执行(一个扭曲)。 NVidia 的内存控制器非常智能,因此如果相邻线程请求 RAM 的相邻字节,它会将这些负载合并为一个可以有效执行的请求。相反,如果 warp 中的每个线程都在访问一个随机内存位置,则整个 warp 必须等待 32 个内存请求完成。此外,对卡内存的读取和写入一次发生整个高速缓存行,因此如果线程在从高速缓存中逐出之前未使用所有读取的 RAM,则会浪费内存带宽。如果您不针对线程块内的连贯内存访问进行优化,预计速度会降低 10 到 100 倍。
(旁注:上述讨论仍然适用于 G80 后的卡;第一代 CUDA 硬件 (G80) 更加挑剔。如果程序员想要合并行为,它还需要对齐的内存请求。)
【讨论】:
以上是关于我应该如何为我不知道大小的许多(1000+)数组分配内存?的主要内容,如果未能解决你的问题,请参考以下文章