C++ 使用哈希合并全局内存写入

C++ 使用哈希合并全局内存写入,c++,c,cuda,gpgpu,C++,C,Cuda,Gpgpu,我的问题涉及到在CUDA中对一组动态变化的数组元素的合并全局写入。考虑下面的内核: __global__ void kernel (int n, int *odata, int *idata, int *hash) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < n) odata[hash[i]] = idata[i]; } 全局无效 内核(int n,int*odata,int*idata,int*has

我的问题涉及到在CUDA中对一组动态变化的数组元素的合并全局写入。考虑下面的内核:

__global__ void
kernel (int n, int *odata, int *idata, int *hash)
{
  int i = blockIdx.x * blockDim.x + threadIdx.x;
  if (i < n)
    odata[hash[i]] = idata[i];
}
全局无效
内核(int n,int*odata,int*idata,int*hash)
{
int i=blockIdx.x*blockDim.x+threadIdx.x;
if(i
这里,数组的第一个
n
元素
hash
包含要从
idata
的第一个
n
元素更新的
odata
索引。很明显,这导致了一个可怕的,可怕的缺乏合并。在我的代码中,一个内核调用的哈希与另一个内核调用的哈希完全无关(其他内核以其他方式更新数据),因此简单地重新排序数据以优化这个特定的kenrel不是一个选项


CUDA中是否有一些功能可以让我改进这种情况下的性能?我听过很多关于纹理内存的讨论,但我无法将我读到的内容转化为这个问题的解决方案。

纹理是一种只读机制,因此它无法直接提高对GMEM的分散写入的性能。如果您是这样“散列”的:

odata[i] = idata[hash[i]]; 
(也许你的算法可以改变?)

那么,考虑一个新方案可能会有一些好处。(您的示例在本质上似乎是1D)


您还可以确保您的共享内存/L1拆分针对缓存进行了优化。不过,这对分散的写入没有多大帮助。

能否限制哈希结果的范围?例如,您可能知道线程的前1K次迭代将仅访问0到8K的
odata


如果是这样,您可以使用共享内存。您可以分配共享内存块,并临时在共享内存上执行快速分散写入。然后在合并事务中将共享内存块写回全局内存。

谢谢您的回复。事实上,在我的代码中,我有很多地方遇到了您描述的情况(从全局内存中分散读取)。这些读取在数组中是真正随机的(通常是稀疏的)。在这种情况下,纹理机制值得研究?在这种情况下,纹理可能会有所帮助。纹理仍然依赖于数据的局部性和重用,以提供任何好处。如果分散读取的净效果是每个位置只读取一次,那么纹理处理将不会有帮助。但是,如果您可能不止一次地读取某些位置(可能来自多个线程),那么纹理处理可能会带来一些改进。