因为我host端的内存结构比较复杂,为了节省空间,每个节点都有自己的单链表。因此为了能拿到device端进行计算,每次在拷贝前,把单链表的内容读取到一维数组,并记录起始长度。
所有的单链表读取完后,一起拷贝到device端进行计算。不知道这样是否可行。
比如现在有3个节点:
1:0,1,2
2:1,2,3
3:4,5
我现在拷贝到一个数组,并用另一个数组作为起始的标记
1:0,1,2,1,2,3,4,5
2:0,2,5,7
不知道这样会不会损害太多的时间。
因为我host端的内存结构比较复杂,为了节省空间,每个节点都有自己的单链表。因此为了能拿到device端进行计算,每次在拷贝前,把单链表的内容读取到一维数组,并记录起始长度。
所有的单链表读取完后,一起拷贝到device端进行计算。不知道这样是否可行。
比如现在有3个节点:
1:0,1,2
2:1,2,3
3:4,5
我现在拷贝到一个数组,并用另一个数组作为起始的标记
1:0,1,2,1,2,3,4,5
2:0,2,5,7
不知道这样会不会损害太多的时间。
LZ您好:
从逻辑上说,您这么做总是可以的,但是考虑到效率有以下两点:
1:您在host端准备数据的时候,可能需要花费一些时间。
2:您在device端,如果是一个线程处理一个节点,那么您相邻线程访存的时候是不连续的,这会造成非合并访问。
如果您链表内容组成的一维数组的数据量较小,那么您可以尝试手工缓冲到shared memory中,然后再使用,虽然可能有bank conflict,但是比在global memory折腾要好一些。
大致如此,祝您编码顺利~
您说的非合并访问时什么意思?我准备的数据量确实很大,因为主要计算就是这些数据,大概怎么也得有1G左右吧…不知道这么大的数据量,还能用这种方法么
LZ您好:
非合并访问就是指不能合并的global memory访问,这是一个CUDA的基本概念,大体是指相邻的线程需要访问一小段连续的显存空间中的数据,才能使访存效率达到最高。
具体解释请参考CUDA C Programming Guide,以及论坛以前的各种讨论。
如果您的数据有1GB的量级,那么显然是无法直接放入shared memory了,您需要整体权衡和考虑您的算法,如果这些数据反复使用,并且计算步骤很多,并且每个节点的数据量较少而只是节点较多,那么或许使用shared memory每次缓冲一小块是可行的。
如果是其他情况,请您结合实际情况考虑,我暂时并无其他建议。
祝您好运~
比如上面我的一维数组里面存储了 0,1,2,1,2,3,4,5
第一个线程访问0,1,2
第二个线程访问1,2,3
第三个线程访问4,5
他们存储在一个一维数组里面,这个数组显然是连续的地址空间,那么属不属于非合并访问?
按照您的访问方式推广到一个warp的线程的访存行为,您这个是非合并访问。
噢,好的,那我再想想其他办法