如何为图像使用托管(统一)内存?

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));

【讨论】:

以上是关于如何为图像使用托管(统一)内存?的主要内容,如果未能解决你的问题,请参考以下文章

如何为Android应用程序统一访问手机后退按钮

如何为项目构建高效的统一文件存储方案

CUDA 统一内存情况下的 DeviceToHost 和 HostToDevice 时间

如何为 Web 应用程序托管音频文件

如何为足球比赛设置球员预制件

Cupy 释放统一内存