由CUDA中的间接访问引起的未合并的全局内存访问

时间:2013-02-28 05:43:04

标签: cuda gpu gpgpu

我的CUDA程序遭受未合并的全局内存访问。虽然第idx个线程只处理数组中的[idx] -th单元格,但是有许多间接内存访问,如下所示。

int idx=blockDim.x*blockIdx.x+threadIdx.x;

.... = FF[m_front[m_fside[idx]]];

对于m_fisde [idx],我们已经合并了访问,但我们实际需要的是FF [m_front [m_fside [idx]]]。有两级间接访问。

我试图在m_front或m_fsied中找到一些数据模式,以使其成为直接顺序访问,但发现它们几乎是“随机”的。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:3)

加速全局内存随机访问:使L1缓存行无效

Fermi和Kepler架构支持全局内存中的两种类型的负载。 完全缓存是 默认模式,它尝试命中L1,然后是L2,然后是GMEM,加载粒度是128字节的行。 L2-only 尝试在L2中命中,然后GMEM和加载粒度为32字节。对于某些随机访问模式,可以通过使L1无效并利用L2的较低粒度来增加存储器效率。这可以通过使用–Xptxas –dlcm=cg的{​​{1}}选项进行编译来完成。

加速全局内存访问的一般准则:禁用ECC支持

Fermi和Kepler GPU支持纠错码(ECC),默认情况下启用ECC。 ECC可降低峰值内存带宽,并可在医疗成像和大规模集群计算等应用中提高数据完整性。如果不需要,它可以 使用Linux上的nvidia-smi实用程序(请参阅link)或Microsoft Windows系统上的“控制面板”禁用以提高性能。请注意,打开或关闭ECC需要重新启动才能生效。

加速开普勒全局内存访问的一般准则:使用只读数据缓存

Kepler为已知为只读的数据提供48KB缓存 功能的持续时间。使用只读路径是有益的,因为它卸载了共享/ L1缓存路径并且它支持 全速未对齐的内存访问。编译器可以自动管理只读路径的使用(使用nvcc关键字)或显式(使用const __restrict内在函数) 程序员。