同一设备内将CUDA Pitched内存复制到1D设备数组的推荐方法
从cudaPitchedPtr复制到1D设备数组的最优方案
好问题!针对你说的同一设备内的内存复制场景,完全不需要逐行复制,CUDA提供了现成的单函数调用方式就能搞定——用cudaMemcpy2D就可以完美实现需求。
为什么cudaMemcpy2D适用?
你创建的cudaPitchedPtr本质是带对齐填充的2D内存块,而cudaMalloc分配的1D数组是连续无填充的内存。cudaMemcpy2D本来就是为处理不同pitch的2D内存复制设计的,我们只需要把1D数组当成“pitch等于每行实际字节数的2D内存”来对待就行。
具体实现代码示例
假设你的元素类型是T,已经通过cudaMalloc3D拿到了cudaPitchedPtr pitched_ptr,且xsize/ysize是对应的宽高,1D数组d_1d已经用cudaMalloc分配好内存:
// 假设T是你的元素类型,比如float、int等 T* d_1d; cudaMalloc(&d_1d, xsize * ysize * sizeof(T)); // 执行复制操作 cudaMemcpy2D( d_1d, // 目标1D数组指针 xsize * sizeof(T), // 目标内存的pitch:因为1D连续,每行字节数就是xsize*sizeof(T) pitched_ptr.ptr, // 源pitched内存的指针 pitched_ptr.pitch, // 源内存的pitch(由cudaMalloc3D自动生成) xsize * sizeof(T), // 每次复制的单行列字节数 ysize, // 要复制的总行数 cudaMemcpyDeviceToDevice // 内存方向:同一设备内选这个,若涉及主机则调整为对应类型 );
关键参数说明
- 目标pitch设置为
xsize * sizeof(T):因为1D数组是连续内存,没有额外的对齐填充,每行的实际字节数就是单个行的元素总大小。 - 源pitch直接用
pitched_ptr.pitch:这是cudaMalloc3D返回的带填充的行宽,cudaMemcpy2D会自动处理源内存的填充部分,只复制有效数据到目标的连续内存中。
这个方法不仅比逐行复制更简洁,而且cudaMemcpy2D是CUDA官方优化过的库函数,性能上和手动逐行复制相当甚至更优。
内容的提问来源于stack exchange,提问作者Soleil
相关产品推荐
相关产品推荐

