我有一个程序(抽象的细节)看起来像这样:
std::vector<cl::Event> events;
for (uint32_t x = 0; x < image_size.x; x += 32) {
for (uint32_t y = 0; y < image_size.y; y += 32) {
events.emplace_back();
cl::Event * event_ptr = &events.back();
cl::NDRange range{ cl::size_type(std::min(image_size.x - x, kernel_size)), cl::size_type(std::min(image_size.y - y, kernel_size)) };
cl::NDRange offset{ cl::size_type(x), cl::size_type(y) };
queue.enqueueNDRangeKernel(kernel, offset, range, {}, nullptr, event_ptr);
}
}
意图是,稍后,当主机完成其任务时,它可以单独查询已保存的事件,尤其是在等待所有事件完成时:
for(cl::Event const& event : events) {
event.wait();
}
/*...*/
但是在我的测试中,我发现enqueueNDRangeKernel
会在一系列关键事件排队后开始阻止,并且当我还在尝试将它们排队时,事件将会运行。有没有办法阻止任何内核运行,直到我明确要求它们启动?像
//PSEUDOCODE
cl::waitEvent trigger;
queue.enqueueWaitEvent(&trigger);
std::vector<cl::Event> events;
for (uint32_t x = 0; x < image_size.x; x += 32) {
for (uint32_t y = 0; y < image_size.y; y += 32) {
events.emplace_back();
cl::Event * event_ptr = &events.back();
cl::NDRange range{ cl::size_type(std::min(image_size.x - x, kernel_size)), cl::size_type(std::min(image_size.y - y, kernel_size)) };
cl::NDRange offset{ cl::size_type(x), cl::size_type(y) };
queue.enqueueNDRangeKernel(kernel, offset, range, {}, nullptr, event_ptr);
}
}
trigger.release(); //All other events behind this event now start running.
/*...*/
但我不知道OpenCL中是否存在这样的机制,或者语法是什么样的。我知道我可以在Vulkan中实现此功能,但我的目标是那些没有Vulkan驱动程序支持的旧硬件。