首页 > 解决方案 > 使用 CL_MEM_USE_HOST_PTR 创建缓冲区时的 CL_OUT_OF_HOST_MEMORY

问题描述

我之前使用 opencl 1.2 包装器的迭代器方法分配缓冲区。但是出于性能原因,我尝试提供一个指向已分配内存的主机指针。但是,当使用此指定缓冲区时,我在 clCreateBuffer 调用中收到 CL_OUT_OF_HOST_MEMORY 错误。

当我将内存分配为 std::vector 并为缓冲区提供迭代器方法时,此代码以前有效,例如

std::vector<int> mem;
mem.resize( 256*256*256, 0);
_d_currentmap= cl::Buffer(*_context,
            mem.begin(), mem.end(), false);

_d_currentmap已创建并且不会引发任何错误。我实际上创建了两个相同大小的缓冲区。

这篇英特尔文章之后,我正在尝试迁移到零复制范例,因为我正在部署与 cpu 共享内存的英特尔高清显卡

首先我初始化要共享的内存,_map1 和 _map2 被初始化。:

int size = 256*256*256;
int* _map1 = (int*)aligned_alloc(4096, sizeof(int)*size);
int* _map2 = (int*)aligned_alloc(4096, sizeof(int)*size);
memset((void*)_map1, 0, size*sizeof(int));
memset((void*)_map2, 0, size*sizeof(int));

然后我想在这些对象之间交换:

int size = 256*256*256*sizeof(int);
int* currptr, newptr;
switch( newmapnumber)
{
case 1:
    memset(_map1, 0, size);
    newptr= _map1;
    currptr= _map2;
    break;
case 2:
    memset(_map2, 0, size);
    newptr =_map2;
    currptr =_map1;
    break;
}
_mapSeq++;

try{
    cl::CommandQueue queue(*_context, CL_QUEUE_PROFILING_ENABLE);
    _d_newmap = cl::Buffer(*_context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size*sizeof(int),(void*) newptr);
    _d_currentmap = cl::Buffer(*_context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size*sizeof(int), (void*)currptr);
    queue.finish();          
 }
 catch (cl::Error err) {
    std::cout << "Exception\n";
    std::cerr
     << "ERROR: "
     << err.what()
     << "("
     << err.err()
     << ")"
     << std::endl;
     exit(1);
 }

这将返回

Exception
ERROR: clCreateBuffer(-6)

这是 cl.h 中定义的 CL_OUT_OF_HOST_MEMORY 错误

标签: opencl

解决方案


好的,没有人会得到这个,因为我没有添加关键信息。两个块之间的 int 大小值发生了变化。

如顶部代码块所示

   int size = 256*256*256;

但是在底部块中,我指定了一个局部变量大小(用于 cl::Buffer 声明)

   int size=256*256*256*sizeof(int);

因此,在缓冲区的声明中,我再次将 size 乘以 sizeof(int):

 _d_newmap = cl::Buffer(*_context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size*sizeof(int),(void*) newptr);

导致缓冲区覆盖和一堆其他的悲痛。


推荐阅读