主机和设备之间的数据传输:
应用程序应尽量减少主机和设备之间的数据传输。 实现这一点的一种方法是将更多的代码从主机移动到设备,即使这意味着运行低并行计算的内核。 中间数据结构可以在设备存储器中创建,由设备操作,并且在没有被主机映射的情况下被销毁或被复制到主机存储器。
而且,由于每次传输的开销比较大,所以将多次小的传输转换为一次较大的传输比较好。
在具有前端总线的系统上,通过使用页面锁定主机内存中,可实现主机和设备之间数据传输的更高性能。
此外,使用映射页面锁定内存(映射内存)时,不需要分配任何设备内存并在设备和主机内存之间显式复制数据。 每次内核访问映射的内存时,都会隐式执行数据传输。 为获得最佳性能,这些内存访问必须与访问全局内存一样(参见设备内存访问)。 假设它们是并且映射的内存仅被读取或写入一次,则使用映射的页锁内存而不是设备和主机内存之间的显式拷贝可以是性能的优化。
在设备内存和主机内存在物理上相同的集成系统上,主机和设备内存之间的任何副本都是多余的,应该使用映射的页面锁定内存。 应用程序可以通过检查集成设备属性(请参阅设备枚举)是否等于1来查询设备是否已集成。
设备内存访问:
访问可寻址存储器(即,全局,本地,共享,常量或纹理存储器)的指令可能需要重新发布多次,这取决于经线内的线程上的存储器地址的分布。 这种分配方式如何影响指令吞吐量,这是每种内存所特有的,下面将分别介绍。 例如,对于全局内存,作为一般规则,地址越分散,吞吐量越低:
全局内存:
全局内存驻留在设备内存中,设备内存通过32,64或128字节内存事务进行访问。 这些存储器事务必须自然对齐:只有与其大小对齐的设备存储器的32,64或128字节段(即,其第一个地址是其大小的倍数)才能被存储器读取或写入传输。
当一个warp执行访问全局内存的指令时,它将warp内线程的内存访问合并为一个或多个这些内存事务,具体取决于每个线程访问的字的大小以及内存地址分配线程。 一般来说,传输是必须的,除了线程访问的字外,还有更多的未使用的字被传送,相应地降低了指令吞吐量。 例如,如果为每个线程的4字节访问生成一个32字节的内存事务,则吞吐量除以8。
需要多少传输以及最终影响吞吐量的多少取决于设备的计算能力。 计算能力3.x,计算能力5.x,计算能力6.x和计算能力7.x给出了有关全局内存访问如何处理各种计算能力的更多细节。
为了最大限度地提高全局内存吞吐量,重要的是通过以下措:
- 遵循基于计算能力3.x,计算能力5.x,计算能力6.x和计算能力7.x的最佳访问模式
- 使用符合器件存储器访问中详述的大小和对齐要求的数据类型,
- 在某些情况下填充数据,例如访问设备内存访问中所述的二维数组时。