多设备环境下的OpenCL缓冲区实例化
OpenCL Buffer Instantiation in a Multi Device Environment
我想知道系统端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。现在我有4x cl::Device对象在ocl_devices.
现在,当我有第二个处理程序类来管理每个设备上的计算时会发生什么:
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);
然后在每个CLASS中,我都实例化了:
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::上下文的,而不是绑定到特定的设备,因此可能会在每个设备上分配四倍的内存地址。我无法确定何时发生"在设备上,此缓冲区从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,总是为所需的每个内核::setArg传递&shared_buffer。我真不知道该怎么办
当你有一个包含多个设备的上下文时,你在该上下文中创建的任何缓冲区对它的所有设备都是可见的。这意味着上下文中的任何设备都可以从上下文中的任何缓冲区中读取数据,并且OpenCL实现负责确保数据在需要时实际移动到正确的设备。如果多个设备同时尝试访问同一个缓冲区,会发生什么情况,这是一些灰色地带,但这种行为通常是避免的。
虽然所有的缓冲区对所有的设备都是可见的,但这并不一定意味着它们将被分配到所有的设备上。我使用过的所有OpenCL实现都使用"首次使用时分配"策略,即缓冲区仅在该设备需要时才在该设备上分配。所以在你的特殊情况下,你应该为每个设备设置一个缓冲区,只要每个缓冲区只被一个设备使用。
理论上,OpenCL实现可能会预先分配所有设备上的所有缓冲区,以防万一它们需要,但我不希望这种情况在现实中发生(我当然从未见过这种情况发生)。如果您运行在一个有可用GPU分析器的平台上,您可以经常使用分析器来查看缓冲区分配和数据移动实际发生的时间和地点,以使自己确信系统没有做任何不希望发生的事情。
- C++字符*缓冲区的大小
- 使用std::vector的OpenCL矩阵乘法
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- OpenCL 代码卡在写入输出缓冲区上
- openCL-创建子缓冲区返回错误代码13
- OpenCL - 从缓冲区读取时CL_INVALID_VALUE
- 如何在 OpenCL 中使用缓冲区分配和映射内存机制
- C++ OpenCL:当缓冲区超出范围时,子缓冲区会发生什么情况?
- 是否可以在同一设备缓冲区上一个接一个地调用 OpenCL 内核?
- OpenCL缓冲区映射/取消映射和入队写入带宽
- Declspec A 结构,当创建要发送到 OpenCL 内核的缓冲区时
- 如何在主机内存上分配 OpenCL 缓冲区的一半,在设备内存上分配另一半
- 使用OpenCL获取OpenGL缓冲区
- 向设备写入缓冲区时发生OpenCL访问冲突
- OpenCL写回缓冲区
- OpenCL缓冲区分配和映射最佳实践
- 分配OpenCL缓冲区时内存地址错误
- OpenCL缓冲区阵列-clEnqueueWriteBuffer-36
- 多设备环境下的OpenCL缓冲区实例化