存储器优化:
内存优化是性能最重要的领域。 目标是通过最大化带宽来最大限度地利用硬件。 使用尽可能多的快速内存和尽可能少的慢速访问内存可以更好地提供带宽。 本章讨论主机和设备上的各种内存以及如何最好地设置数据项以有效使用内存。
主机和设备之间的数据传输:
设备内存与GPU之间的峰值理论带宽要高得多(例如NVIDIA Tesla M2090为177.6 GB / s),而不是主机内存与设备内存之间的理论峰值(PCIe x16 Gen2为8 GB / s)。 因此,为了获得最佳的整体应用程序性能,尽量减少主机和设备之间的数据传输非常重要,即使这意味着在GPU上运行的内核与在主机CPU上运行内核相比不会显示任何加速。
高优先级:尽可能减少主机和设备之间的数据传输,即使这意味着在设备上运行某些内核时,与在主机CPU上运行内核相比,它们不会显示性能增益。
中间数据结构应该在设备存储器中创建,由设备操作,并在没有被主机映射或复制到主机内存的情况下销毁。
而且,由于与每次传输相关的开销,将许多小传输分配到一个更大的传输中比单独进行每次传输明显更好,即使这样做需要将不连续的存储区域打包到连续缓冲区中,然后在传输之后解包。
最后,使用页面锁定(或锁定)存储器时,主机和设备之间的带宽将更高。
固定内存(Pinned Memory):
页面锁定或固定内存传输可实现主机和设备之间的最高带宽。 例如,在PCIe x16 Gen2卡上,固定内存可达到大约6GB / s的传输速率。
固定内存是使用运行时API中的cudaHostAlloc()函数分配的。 bandwidthTest CUDA示例演示如何使用这些函数以及如何测量内存传输性能。
对于已经预先分配的系统内存区域,可以使用cudaHostRegister()来实时锁定内存,而无需分配单独的缓冲区并将数据复制到内存中。
固定的内存不应该被过度使用。 过度使用可能会降低整体系统性能,因为固定内存是一种稀缺资源,但多少事先难以预知。 此外,与大多数正常的系统内存分配相比,系统内存的固定是一项重量级操作,因此在进行所有优化时,测试应用程序及其运行的系统以获得最佳性能参数。
计算异步和重叠传输:
使用cudaMemcpy()在主机和设备之间传输数据会阻止传输; 也就是说,只有在数据传输完成后,控制权才会返回到主机线程。 cudaMemcpyAsync()函数是cudaMemcpy()的非阻塞变体,其中控件立即返回到主机线程。 与cudaMemcpy()相比,异步传输版本需要固定主机内存,并且它包含额外的参数,流ID。 流只是在设备上按顺序执行的一系列操作。 不同流中的操作可以交错并且在某些情况下可以重叠 - 可用于隐藏主机和设备之间数据传输的属性。
异步传输以两种不同的方式实现数据传输与计算的重叠。 在所有支持CUDA的设备上,可以将主机计算与异步数据传输和设备计算重叠。 例如,重叠计算和数据传输演示如何执行例程cpuFunction()中的主机计算,同时将数据传输到设备并使用该设备执行内核。