【发布时间】:2014-03-13 04:31:52
【问题描述】:
我想知道系统端 cl::Buffer 对象如何在多设备上下文中实例化。
假设我有一个 OCL 环境类,它从 cl::Platform 生成一个 cl::Context:
this->ocl_context = cl::Context(CL_DEVICE_TYPE_GPU, con_prop);
然后,对应的一组设备:
this->ocl_devices = this->ocl_context.getInfo<CL_CONTEXT_DEVICES>();
我为每个设备生成一个 cl::CommandQueue 对象和一组 cl::Kernel(s)。
假设我有 4 个相同类型的 GPU。现在我在 ocl_devices 中有 4 个 cl::Device 对象。
现在,当我有第二个处理程序类来管理每个设备上的计算时会发生什么:
oclHandler h1(cl::Context* c, cl::CommandQueue cq1, std::vector<cl::Kernel*> k1);
...
oclHandler h2(cl::Context* c, cl::CommandQueue cq4, std::vector<cl::Kernel*> k4);
然后在每个类中,我都实例化:
oclHandler::classMemberFunction(
...
this->buffer =
cl::Buffer(
*(this->ocl_context),
CL_MEM_READ_WRITE,
mem_size,
NULL,
NULL
);
...
)
然后写到
oclHandler::classMemberFunction(
...
this->ocl_cq->enqueueWriteBuffer(
this->buffer,
CL_FALSE,
static_cast<unsigned int>(0),
mem_size,
ptr,
NULL,
NULL
);
...
this->ocl_cq.finish();
...
)
每个缓冲区。有人担心,因为实例化是针对 cl::context,而不是绑定到特定设备,所以每个设备上可能有四倍的内存地址分配。我无法确定“在设备上,此缓冲区从 0xXXXXXXXXXXXXXXXX 运行 N 个字节”的操作何时发生。
应该为每个设备实例化一个上下文吗?这似乎不自然,因为我必须实例化一个上下文。看看有多少个设备,然后再实例化 d-1 多个上下文....似乎效率低下。我担心的是限制可用内存设备方面。我正在对大量数据集进行计算,我可能会使用每张卡上所有可用的 6GB。
谢谢。
编辑:有没有办法在不使用命令队列的情况下实例化缓冲区并异步填充它?就像假设我有 4 台设备和一个充满静态只读数据的缓冲区主机端。假设缓冲区大小为 500MB。如果我只想使用 clCreateBuffer,与
shared_buffer = new
cl::Buffer(
this->ocl_context,
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
total_mem_size,
ptr
NULL
);
这将启动阻塞写入,在将所有 ptr 的内容复制到新分配的内存之前,我无法在主机端执行任何操作。我有一个多线程设备管理系统,我为每个设备创建了一个 cl::CommandQueue,总是为每个所需的 kernel::setArg 传递 &shared_buffer。我很难思考该怎么做。
【问题讨论】: