2015-11-03 92 views
0

CUDA documentation建议使用cudaMemCpy2D()用于2D阵列(以及类似地cudaMemCpy3D()用于3D阵列),而不是用于cudaMemCpy()更好的性能更适当地前者分配器件存储器中连续行。另一方面,所有cudaMemCpy函数,就像memcpy()一样,都需要连续分配内存。2D阵列,在堆存储器cudaMemCpy2D()

如果我将我的(主机)阵列创建为例如float myArray[h][w];,那么这很好。

float** myArray2 = new float*[h]; 
for(int i = 0 ; i < h ; i++){ 
    myArray2[i] = new float[w]; 
} 

这不是当一个人试图实现CUDA到现有的项目,这是我面临的问题,除了一个大问题:但是,它很可能不会,如果我使用类似的工作。现在,我创建一个临时一维数组,将我的二维数组的内容复制到其中,并使用cudaMemCpy()并重复整个过程以在内核启动后获得结果,但这似乎不是一种优雅/有效的方式。

有没有更好的方法来处理这种情况?具体来说,有没有办法在堆上连续分配行来创建真正的二维数组,以便我可以使用cudaMemCpy2D()

PS:我找不到这个问题的答案如下以前类似的帖子:(在 第二个答案这个是相当令人费解)

+0

我不清楚为什么你的第二个环节不是解决方案。 –

+0

@AnonMail,我可能是错的,但在这个问题中定义了一个容器(类似于std :: vector)。它在内部使用一维数组来实现连续分配。也类似于std :: vector和std :: map,不能使用指针直接访问容器的元素,而应该使用迭代器。我怀疑可以使用memcpy()复制这些对象的内容。 –

+0

@RobertCrovella,感谢您的评论。这(在HostToDevice副本之前手动压扁2D阵列)正是我现在在我的应用程序中所做的。我希望能找到一种方法来改变它,所以我可以利用cudaMemCpy2D()的更高效的内存分配。看起来这是唯一的方法。 –

回答

2

分配大数组,然后使用指针算法来查找行的实际开始。

float* bigArray = new float[h * w] 
float** myArray2 = new float*[h] 
for(int i = 0 ; i < h ; i++){ 
    myArray2[i] = &bigArray[i * w]; 
} 

你的指针数组myArray2给你C/C++式二维阵列的行为,bigArray给你的存储器由CUDA所需的连续块中。

+0

谢谢,@戴尔威尔逊。只是为了澄清,这样我可以将myArray2传递给cudaMemCpy2D(),对不对? –

+0

请注意,我编辑我的帖子,使第一行新float [h * w]而不是新float * [h * w]。对于错字感到抱歉。现在谈谈你的问题:你应该使用bigArray将数组传递给CUDA,但是你也可以使用myArray [0]。在任何情况下,您都需要一个指向连续浮点数组的指针,而不是指向数组的指针,这是传递myArray2会给你的指针。 –

+0

太棒了!这正是我所希望的。谢谢。 –