CUDA高效的内存访问

时间:2011-06-08 16:08:20

标签: cuda

我想将图像存储到设备中,我想处理它。 我正在使用以下内容将图像复制到内存中。

int *image = new int[W*H];
//init image here
int  *devImage;
int sizei = W*H*sizeof(int);
cudaMalloc((void**)&devImage, sizei);
cudaMemcpy(devImage, image, sizei, cudaMemcpyHostToDevice);
//call device function here.

我有两个设备功能。在第一个函数中,我从左到右访问图像,在第二个函数中,我从上到下访问它。我发现从左到右相比,从上到下的访问时间非常短。这是因为访问内存所需的时间。 如何有效地访问CUDA中的内存?

2 个答案:

答案 0 :(得分:4)

这听起来可能是合并内存访问的问题。您应该尝试让连续的线程从内存中访问连续的元素。

例如,假设您使用10个线程(编号为0-9)并且您正在使用10x10元素数据集。很容易想象在网格中布局的数据,如下图所示,但是,在内存中,您在代码中声明它的方式,以线性方式布局,如100 -element 1D数组。

 0,  1,  2,  3...   9,
10, 11, 12, 13...  19,
20, 21, 22, 23...  29,
30, 31, 32, 33...  39,
 .   .              .
 .        .         .
 .             .    .
90, 91, 92, 93...  99

听起来你的第一个实现“从上到下”正在执行合并读取 - 十个线程在元素0,1,2,3 ... 9,然后10,11,12,13上运行。这些读取是合并的,因为十个线程读取了一维线性存储器布局中相邻的十个元素。

听起来你的第二个实现“从左到右”可能是以非合并的方式访问你的数组 - 十个线程在元素0,10,20,30 ...... 90上运行,然后是1,11, 21,31 ... 91等。在这种情况下,读取是未合并的,因为十个连续的线程正在读取实际相距很远的存储器位置。 请记住,在一维线性存储器布局中,元素12和22是十个彼此远离的存储器地址!

“最佳实践指南”在3.2.1节中讨论了合并访问的重要性,并且在this post中对合并访问进行了很好的描述。

答案 1 :(得分:-2)

随机访问 - 使用纹理内存或表面内存..