我在Intel Core i7-7600U的iGPU上遇到异步数据传输问题。
代码的核心部分来自一个简单的例子:
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
auto platform = platforms.front();
std::vector<cl::Device> devices;
platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
auto device = devices.front();
cl::Context context(device);
char buf[16];
cl::Buffer memBuf(context, CL_MEM_READ_WRITE, sizeof(buf));
cl::CommandQueue queue(context, device);
cl::Event ev;
queue.enqueueWriteBuffer(memBuf, CL_FALSE, 0, sizeof(buf), buf, NULL, &ev);
int status;
do{
ev.getInfo(CL_EVENT_COMMAND_EXECUTION_STATUS, &status);
}while(status != 0);
std::cout << "DONE" << std::endl;
它应该做的是忙于等待数据传输。这可以包含在调度程序中(并且在starPU中)
然而它并没有通过循环。当我使用CPU(CL_DEVICE_TYPE_CPU
)时,它可以工作。当我使用ev.wait()
或queue.finish()
时,它可以正常工作。
这是英特尔的错误吗? OpenCL标准中是否有任何内容允许实现延迟调度,直到实际等待它为止?
供参考:使用Linux Mint,内核4.13.0-32-generic #35~16.04.1-Ubuntu SMP
来自https://software.intel.com/en-us/articles/opencl-drivers(intel-opencl-r5.0(SRB5.0)Linux驱动程序包)的OpenCL运行时通过以下方式安装:
sudo alien --to-deb *.rpm
sudo dpkg -i *.deb
sudo ln -s /opt/intel/opencl/include/CL /usr/local/include/CL
sudo apt-get install ocl-icd-libopencl1
答案 0 :(得分:2)
在您调用clFlush
或clFinish
函数之前,clEnqueueXXX排队的OpenCL命令不会开始执行。
clFlush
基本上将所有命令从CL_QUEUED
状态移至CL_SUBMITTED
状态(有关所有状态的列表,请参阅clGetEventInfo文档)。
clFinish
与clFlush
的作用相同,但也会阻塞,直到队列中的所有命令都完成执行。
在您的示例中,您应该在循环之前添加clFlush
调用以使其正常工作。
编辑:一些OpenCL实现可以在排队后执行隐式clFlush,因此命令可以在clEnqueueXXX调用之后立即启动。这不是可移植的,对于一般情况,您仍应使用clFlush
或clFinish
。