异步 enqueueWriteBuffer 未在 Intel OpenCL for iGPU 上执行
Asynchronous enqueueWriteBuffer not executed on Intel OpenCL for iGPU
我在 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 的 OpenCL 运行时(intel-opencl-r5.0 (SRB5.0) Linux 驱动程序包)并通过以下方式安装:
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
由 clEnqueueXXX 排队的 OpenCL 命令不会开始执行,直到您调用 clFlush
或 clFinish
函数。
clFlush
基本上将所有命令从 CL_QUEUED
状态移动到 CL_SUBMITTED
状态(有关所有状态的列表,请参阅 clGetEventInfo 文档)。
clFinish
与 clFlush
的作用相同,但也会阻塞直到队列中的所有命令完成执行。
在您的示例中,您应该在循环之前添加 clFlush
调用以使其工作。
编辑:一些 OpenCL 实现可以在入队后执行隐式 clFlush,因此命令可以在 clEnqueueXXX 调用后立即启动。这不是可移植的,对于一般情况,您仍应使用 clFlush
或 clFinish
.
我在 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 的 OpenCL 运行时(intel-opencl-r5.0 (SRB5.0) Linux 驱动程序包)并通过以下方式安装:
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
由 clEnqueueXXX 排队的 OpenCL 命令不会开始执行,直到您调用 clFlush
或 clFinish
函数。
clFlush
基本上将所有命令从CL_QUEUED
状态移动到CL_SUBMITTED
状态(有关所有状态的列表,请参阅 clGetEventInfo 文档)。clFinish
与clFlush
的作用相同,但也会阻塞直到队列中的所有命令完成执行。
在您的示例中,您应该在循环之前添加 clFlush
调用以使其工作。
编辑:一些 OpenCL 实现可以在入队后执行隐式 clFlush,因此命令可以在 clEnqueueXXX 调用后立即启动。这不是可移植的,对于一般情况,您仍应使用 clFlush
或 clFinish
.