Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cuda 高效内存访问_Cuda - Fatal编程技术网

Cuda 高效内存访问

Cuda 高效内存访问,cuda,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 funct

我想将图像存储到设备中并对其进行处理。 我正在使用以下命令将图像复制到内存中

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中的内存

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

例如,假设您正在使用10个线程(编号为0-9),并且您正在操作一个10x10元素数据集。很容易将数据按如下所示的方式绘制成网格,但是,在内存中,按照您在代码中声明的方式,它是以线性方式排列的,,作为一个100元素的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。。。19等。由于十个线程读取一维线性内存布局中相邻的十个元素,因此这些读取被合并

听起来您的第二个实现“从左到右”可能是以非协调的方式访问您的数组——十个线程在元素0、10、20、30上运行。。。90,然后是1,11,21,31。。。91等。在这种情况下,由于十个连续的线程正在读取实际上相距很远的内存位置,因此读取是不可恢复的记住,在1D线性内存布局中,元素12和22彼此相隔十个内存地址


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

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

我认为您应该阅读nVidia提供的CUDA C最佳实践指南和CUDA C编程指南。之后,您就可以很容易地理解内核之间的性能差异。内存访问模式已经在这里以及nVidia论坛和谷歌上进行了广泛讨论。