2012-08-15 18 views
0

我的程序分析了一个视频文件,它被表示为一个3d数组并且从LabView发送到我的程序。 LabView已经将这个3d数组变成了一个1d数组,所以我刚刚在CUDA中分配一个1d数组,使用cudaMalloc并使用cudaMemcpy来复制数据。但是我注意到,如果我发送超过2XXX,120x240像素图像,我从我的一些cuda内存函数(cudamemcpy和cudafree,稍后在我的程序中发生一些内核被调用后)中收到“未知错误”,以及这些最终会破坏我的计划。但是,如果我降低数量,如果我发送的图像,我没有问题。这让我相信我的代码很好,但是我的内存分配实践很糟糕。当发送非常大的阵列时,Cuda记忆功能给出“未知错误”

首先,让我们来谈谈Pitched的记忆。据我所知,这是所有关于选择一个好的大小来分配内存,以便线性数据不会分成两个块。这对于2D和3D阵列尤其常见,因为您希望将行或列放在内存中以便快速访问。

如果我不使用倾斜内存,会发生这些问题吗?不使用倾斜内存时会发生什么样的错误,特别是对于这些非常大的数组?到目前为止,我忽略了使用cudaMallocPitch和cudaMalloc3d的选项,尽管我在技术上有2d和3d数组,我已经放平了。

最后,当cudaGetLastError只告诉我“未知错误”时,如何进一步调试我的代码问题?我能够找到哪个函数存在错误,但是当它像cudaFree一样时,我无法调试这种东西,或者找出问题的起源地。

无论如何,感谢您的帮助。

回答

2

不使用倾斜内存的成本是速度。如果两个线程试图访问视频的相邻帧并且帧被分配在连续内存中(没有对齐),则一个帧的部分将与另一个帧驻留在相同的内存块或缓存线中,并且一个线程可能必须等到另一个线程完成其内存操作。可能不致命,但绝对不是最佳。那里可能还有写后读或写后写问题。

使用倾斜内存的成本是,如果您的元素(帧或扫描线)大小不是首选对齐边界的偶数倍,它将稍微增加内存分配。下一帧或扫描行的开始可能需要填充几个字节,以使其在适当的存储器地址边界上开始。为每个帧或扫描行大小添加30个字节以获得2000帧的适当边界,将为您​​的总内存分配增加大约60,000个字节。

如果总数据集不适合设备内存,则必须将数据集分成更小的块,并对您的cuda内核进行多次调用以处理每个块。如果您的代码不需要随时访问整个数据集,切换到流式传输模式可以大大减少整体处理时间。当一个warp正在等待其数据块加载到设备内存中时,另一个warp可能正在处理其块,因此CUDA内核不会闲置。

如果您的视频处理代码需要看到4个连续的帧缓冲区来完成它的工作,那么您可以设计一个缓冲区管理系统,在队列中不再需要时从队列中取消最旧的帧并设置准备下一个内核调用的新框架。更好 - 为新帧重新使用旧帧存储器,以避免内存分配的开销。

只加载你需要的,什么时候(或者刚好在你真的需要它的时候)。这就是20美元的视频播放器和录像机芯片如何实时处理多千兆字节的视频流,而且只需要少量的实际RAM。