【问题标题】:CUDA 128 bytes read in a single instruction单条指令读取 CUDA 128 字节
【发布时间】: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


【解决方案1】:

所有内存事务(在可能的情况下)基于每个warp 发出。因此,您要询问的 128 字节事务是当一个扭曲中的所有 32 个线程发出一个内存加载指令时,该指令可以在单个“合并”事务中提供服务。单个线程不能发出大内存事务,只有 32 个线程的 warp 可以,并且只有在您运行代码的任何架构的内存合并要求都能得到满足时。

我无法真正理解您对代码实际执行的描述,但仅从第一原则来看,答案似乎是否定的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多