Optimization 减少CPU到GPU数据传输延迟的技术

Optimization 减少CPU到GPU数据传输延迟的技术,optimization,memory,cuda,data-transfer,latency,Optimization,Memory,Cuda,Data Transfer,Latency,我一直在寻找减少从CPU和GPU来回传输数据造成的延迟的方法。当我第一次开始使用CUDA时,我注意到CPU和GPU之间的数据传输确实需要几秒钟的时间,但我并不在意,因为我正在编写的小程序并不关心这一点。事实上,对于绝大多数使用GPU(包括视频游戏)的程序来说,延迟可能不是什么大问题,因为它们仍然比在CPU上运行快得多 然而,我有点热衷于HPC,当我看到天河一号理论峰值失败与LINPACK实际测量性能之间的巨大差异时,我开始关注我的研究方向。这引起了我对自己是否走上了正确的职业道路的担忧 通过使用

我一直在寻找减少从CPU和GPU来回传输数据造成的延迟的方法。当我第一次开始使用CUDA时,我注意到CPU和GPU之间的数据传输确实需要几秒钟的时间,但我并不在意,因为我正在编写的小程序并不关心这一点。事实上,对于绝大多数使用GPU(包括视频游戏)的程序来说,延迟可能不是什么大问题,因为它们仍然比在CPU上运行快得多

然而,我有点热衷于HPC,当我看到天河一号理论峰值失败与LINPACK实际测量性能之间的巨大差异时,我开始关注我的研究方向。这引起了我对自己是否走上了正确的职业道路的担忧

通过使用cudaHostAlloc()函数使用固定内存(页面锁定)内存是减少延迟的一种方法(相当有效),但是还有其他我不知道的技术吗?更清楚的是,我说的是优化代码,而不是硬件本身(这是NVIDIA和AMD的工作)


作为一个附带问题,我知道戴尔和惠普出售特斯拉服务器。我很好奇GPU对数据库应用程序的利用程度,在数据库应用程序中,您需要从硬盘驱动器(HDD或SSD)进行持续读取,这是一个只有CPU才能执行的操作,

您可以使用
cudaMemcpyAsync()
将您在CPU上所做的工作与内存传输重叠。这不会降低数据传输的延迟,但可以提高算法的整体性能。指南中有一些相关信息。

有几种方法可以解决CPU-GPU通信开销-我希望这就是您所说的延迟,而不是传输本身的延迟。请注意,我故意使用术语address而不是reduce,因为如果可以隐藏它,则不一定需要减少延迟。还要注意的是,我对CUDA更为熟悉,所以下面我只提到CUDA,但OpenCL中也提供了一些功能

正如您所提到的页面锁定内存具有增加存储容量的目的。此外,可以将页面锁定主机内存映射到GPU,这种机制允许直接访问从GPU内核分配的数据,而无需额外的数据传输。这种机制称为零拷贝传输,如果数据只读/写一次并伴随大量计算,并且对于没有单独内存(移动)的GPU,这种机制非常有用。但是,如果访问零拷贝数据的内核没有强计算限制,因此无法隐藏数据访问的延迟,那么页面锁定而非映射内存将更有效。此外,如果数据不适合GPU内存,零拷贝仍将工作。
请注意,过多的页面锁定内存可能会导致CPU端严重减速

正如tkerwin所提到的,从不同的角度来处理这个问题,异步传输(wrt CPU线程与GPU对话)是通过CPU上的计算与传输重叠来隐藏CPU-GPU传输延迟的关键。这可以通过
cudaMemcpyAsync()
以及使用异步内核执行的零拷贝来实现。
通过使用多个流将传输与内核执行重叠,可以进一步实现这一点。注意,流调度可能需要特别注意良好的重叠;特斯拉和Quadro卡具有双DMA引擎,可实现与GPU之间的同步数据传输。 此外,使用CUDA 4.0,从多个CPU线程使用GPU变得更容易,因此在多线程CPU代码中,每个线程都可以将自己的数据发送到GPU并更容易地启动内核

最后,为CUDA实现了一个非对称共享内存模型。它的一个非常有趣的特性是它提供的一致性模型,特别是延迟和滚动更新,只允许以阻塞方式传输在CPU上修改的数据。

有关更多详细信息,请参阅以下文章:.

如果延迟是一个问题,那么您可能需要研究AMD fusion体系结构的折衷方案。您得到的延迟大大减少,并且在某些情况下可以比CPU从RAM传输更快。然而,使用精简的非离散GPU确实会对性能造成影响。

你可能会发现这很有趣:@Misha你是对的,这篇文章描述了我想到的挑战。感谢…关于天河IA的低浮点效率:尽管GPU具有巨大的运算能力(ideed通常很难充分利用),但不要忘记GPU内存体系结构也发挥着重要作用,甚至计算绑定内核也可以大大优于CPU实现。