我有一个大型阵列(比如512K元素),GPU驻留,其中只需要处理一小部分元素(比如5K随机分布元素 - 集合S)。找出哪些元素属于S的算法非常有效,因此我可以轻松地创建一个指针数组或索引到集合S中的元素。
仅对来自S的元素运行CUDA或OpenCL内核的最有效方法是什么?我可以在阵列A上运行内核吗?到目前为止,我见过的所有例子都涉及连续的1D,2D或3D数组。引入一层间接是否有任何问题?
答案 0 :(得分:4)
在CUDA连续(非随机)内存访问是首选,因为可能使用内存合并。创建随机分布的索引数组并从每个线程的A中继续一个索引并不是什么大问题,如下所示:
__global__ kernel_func(unsigned * A, float * S)
{
const unsigned idx = threadIdx.x + blockIdx.x * blockDim.x;
const unsigned S_idx = A[idx];
S[S_idx] *= 5; // for example...
...
}
但对S [随机访问]的内存访问速度非常慢(这将是最可能的瓶颈)。
如果您决定使用CUDA,那么您必须尝试使用块/网格大小,最大限度地减少每个线程的寄存器消耗(以最大化每个多处理器的块数),并且可以排序A以使用距离最近的线程最近的S_ind ...
答案 1 :(得分:1)
如果你对索引进行排序或构建排序的列表将有助于性能分配,如果有索引集群,那么尝试使用纹理内存,如果你从每个线程中访问一些元素,我找到了一些使用共享内存可以显着提升性能。
答案 2 :(得分:1)
对于一个间接级别没有任何问题。我在自己的CUDA代码中使用了相当数量的金额。随着时间的推移,集合S是否可能保持静态?如果是这样,很可能值得生成查找A,就像你说的那样。
此外,纹理内存将成为您提供缓存局部性的朋友。您使用的纹理类型(1D,2D或3D)将取决于您的问题。