我有一个处理图像/视频的 OpenCL 管道,它有时会占用大量内存。它像这样在 cl::Buffer() 分配上崩溃:
cl_int err = CL_SUCCESS;
cl::Buffer tmp = cl::Buffer(m_context, CL_MEM_READ_WRITE, sizeData, NULL, &err);
错误 -4 - cl_mem_object_allocation_failure
。
这通过使用非常大的图像发生在我的管道中的固定点。如果我只是将图像缩小一点,它就会在这个非常占用内存的部分通过管道。
我可以访问带有 4go 的 Nvidia 卡,但在某个时间点出现故障,并且还尝试使用带有 2go 的 AMD GPU,但较早出现故障。
根据这个thread ,由于与 VRAM 交换,无需知道当前分配,但似乎我的管道破坏了我设备的内存。
所以这是我的问题:
1) 我的计算机或管道是否有任何设置以允许更多 VRAM?
2) 是否可以使用 CL_DEVICE_GLOBAL_MEM_SIZE
作为要分配的最大大小的引用,或者我需要做 CL_DEVICE_GLOBAL_MEM_SIZE
-(本地内存 + 私有(private)) ,或类似的东西?
根据我自己的内存分析器,我在崩溃时分配了 92% 的 CL_DEVICE_GLOBAL_MEM_SIZE
。通过稍微调整大小,管道表示我在调整后的图像上使用了 89% 并且它通过了,所以我假设我的大图像处于通过的边缘。
最佳答案
您设备的 VRAM 的某些部分可能用于像素缓冲区、常量内存或其他用途。对于 AMD 卡,您可以设置环境变量 GPU_MAX_HEAP_SIZE
和 GPU_MAX_ALLOC_PERCENT
以使用更大部分的 VRAM,但这可能会产生意想不到的副作用。两者都表示为卡上物理可用内存的百分比。此外,每个内存分配的大小都有限制。您可以通过查询 CL_DEVICE_MAX_MEM_ALLOC_SIZE
获得单个内存分配的最大大小,它可能小于 CL_DEVICE_GLOBAL_MEM_SIZE
。对于 AMD 卡,可以使用 GPU_SINGLE_ALLOC_PERCENT
控制此大小。这不需要更改代码,只需在调用可执行文件之前设置变量即可:
GPU_MAX_ALLOC_PERCENT="100"
GPU_MAX_HEAP_SIZE="100"
GPU_SINGLE_ALLOC_PERCENT="100"
./your_program
关于c++ - OpenCL 管道无法使用 cl_mem_object_allocation_failure 分配缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55383011/