如何为图像使用托管(统一)内存?
Posted
技术标签:
【中文标题】如何为图像使用托管(统一)内存?【英文标题】:How can you use managed (unified) memory for an image? 【发布时间】:2021-09-02 20:51:18 【问题描述】:昨天我花了一整天时间阅读如何为 CUDA 程序使用托管(统一)内存阵列(使用书 Professional CUDA Programming,练习了一些示例代码(尽管我仍然对探查器信息有疑问)并且我我准备将它应用到我的程序中,该程序同时使用了 CUDA 内核和一些 OpenCV 函数。
我有几个问题,但让我在这里解决第一个问题。
我有
cv::Mat h_image;
h_image = cv::imread(dirname+image_filenames[ni], cv::IMREAD_GRAYSCALE);
cv::cuda::GpuMat d_image;
// 2. Upload the Image
d_image.upload(h_image);
所以我用imread
读取了一张图片,并将其上传到设备内存。
如何为此使用统一内存?
理论上,我可以使用统一内存(使用浮点数组)
float *A;
cudaMallocManaged((void **)&A, nBytes);
甚至(我更喜欢这个)
__device__ __managed__ float A[67108864];
有没有办法用 Mats 和 GpuMats 做类似的事情?
【问题讨论】:
【参考方案1】:我找到了一个答案(还没有尝试过)here,实际上是一个非常好的答案,因为它解释了使用统一内存和固定内存
基本上就是这么用的
#ifndef USE_UNIFIED_MEM
/* Pinned memory. No cache */
std::cout << "Using pinned memory" << std::endl;
void *device_ptr, *host_ptr;
cudaSetDeviceFlags(cudaDeviceMapHost);
cudaHostAlloc((void **)&host_ptr, frameByteSize, cudaHostAllocMapped);
cudaHostGetDevicePointer((void **)&device_ptr, (void *) host_ptr , 0);
cv::Mat frame_out(height, width, CV_8UC3, host_ptr);
cv::cuda::GpuMat d_frame_out(height, width, CV_8UC3, device_ptr);
#else
/* Unified memory */
std::cout << "Using unified memory" << std::endl;
void *unified_ptr;
cudaMallocManaged(&unified_ptr, frameByteSize);
cv::Mat frame_out(height, width, CV_8UC3, unified_ptr);
cv::cuda::GpuMat d_frame_out(height, width, CV_8UC3, unified_ptr);
#endif
我将尝试这个但不动态分配它但也使用__device__ __managed__
【讨论】:
【参考方案2】:这是另一个让所有 CV mat 使用共享内存的选项
cv::Mat::setDefaultAllocator(cv::cuda::HostMem::getAllocator(cv::cuda::HostMem::AllocType::SHARED));
【讨论】:
以上是关于如何为图像使用托管(统一)内存?的主要内容,如果未能解决你的问题,请参考以下文章