我是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次读取(int + double4)的double4 + 65次读数(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%。
答案 0 :(得分:3)
在 per warp 的基础上发布所有内存事务(如果可能)。因此,您要问的128字节事务是当warp中的所有32个线程发出内存加载指令时,可以在单个“合并”事务中进行服务。单个线程不能发出大内存事务,只有32个线程的warp可以,并且只有当你运行代码的任何体系结构的内存合并要求都可以满足时。
我无法真正按照你的代码实际所做的描述,但仅从第一原则来看,答案似乎是否定的。