【发布时间】:2013-06-27 17:12:53
【问题描述】:
我是 CUDA 新手,目前正在优化现有的分子动力学应用程序。它的作用是使用带有坐标的 double4 数组并根据邻居列表计算力。我用以下几行编写了一个内核:
double4 mPos=d_arr_xyz[gid];
while(-1!=(id=d_neib_list[gid*MAX_NEIGHBORS+i])){
Calc(gid,mPos,AA,d_arr_xyz,id);i++;
}
然后 Calc 采用 d_arr_xyz[id] 并计算力。这会在每次调用 Calc 时读取 1 次 double4 + 65 次 (int +double4) 读取(65 是每个粒子在 d_neib_list 中的平均邻居数(不等于 -1))。
是否可以减少这些读取?不同粒子的邻居列表,即 d_arr_xyz[gid] 和 d_arr_xyz[id] 不相关,因此我不能将共享内存用于线程块来缓存 d_arr_xyz。
我看到的是,如果以某种方式在一个或几个大型事务中将整个列表 int*MAX_NEIGHBORS 加载到共享内存中,这将删除 65 次单独的 int 读取。
所以问题是:是否有可能这样做,以便将这 65 次 int 读取转换为几个大事务。我在文档中读到读取的长度甚至可以是 128 个字节。我到底应该写什么以便汇编程序进行 1 次大调用?
更新:
感谢您的回复。从下面用户 talonmies 的答案中,我更改了替换邻居矩阵的维度 x 和 y 的代码。现在连续的线程加载连续的 int[gid],我猜这可能会导致 128 字节的读取。该程序的运行速度提高了 8%。
【问题讨论】:
-
如果你有
N粒子和Pcores,那么,如果每个核心都分配了一些N/P粒子,如果你存储邻域信息,你可能会节省一些全局内存事务将每个粒子放入共享内存中。还请查看Accelerating molecular dynamics simulations using GPUs with CUDA,第 5 节。只需掌握主要概念并考虑到本文处理的是非常古老的架构。
标签: memory optimization cuda