【问题标题】:Asynchronous enqueueWriteBuffer not executed on Intel OpenCL for iGPU异步 enqueueWriteBuffer 未在 Intel OpenCL for iGPU 上执行
【发布时间】:2018-02-15 16:39:30
【问题描述】:

我在 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

【问题讨论】:

    标签: asynchronous opencl intel gpgpu


    【解决方案1】:

    由 clEnqueueXXX 排队的 OpenCL 命令不会开始执行,直到您调用 clFlushclFinish 函数。

    • clFlush 基本上将所有命令从CL_QUEUED 状态移动到CL_SUBMITTED 状态(有关所有状态的列表,请参阅clGetEventInfo 文档)。

    • clFinish 的作用与clFlush 相同,但也会阻塞,直到队列中的所有命令都执行完毕。

    在您的示例中,您应该在循环之前添加 clFlush 调用以使其工作。

    编辑:一些 OpenCL 实现可以在入队后执行隐式 clFlush,因此命令可以在 clEnqueueXXX 调用后立即启动。这不是可移植的,一般情况下,您仍应使用clFlushclFinish

    【讨论】:

    • 由于 CL_QUEUED 是一个有效的返回值,您会认为不需要 clFlush。 OP:状态等于什么?这应该提供线索。
    • 是,状态为CL_QUEUED。有趣的是 a) 我不知道我需要刷新 OCL 队列和 b) 2010 年创建的库/运行时显然存在错误。同样奇怪的是,您不需要为主机设备刷新。
    • @Dithermaster CL_QUEUED 表示它已被放入命令队列的“TODO 列表”。 CL_SUBMITTED 表示已经实际提交给设备执行。实现可以选择立即向设备提交命令,但也可以选择分批提交(在 clFlush 上),以获得更好的性能。 GPU 通常是后者。
    • 详细说明“已提交”:我认为最好想到CL_QUEUED = 在主机端列表中排队,CL_SUBMITTED = 在设备端列表中排队。原因是,它可能仍然在设备驱动程序中,而不是实际上在设备中(这通常无关紧要)。但是,基本的工作流程是:通过在主机上排队进行准备,提交到设备,等待执行并随后同步(完成)。所有这些都由一个状态指示
    • @Andrew 您能否通过提及执行可以在 clFlush 之前开始来更新答案?因为这就是 CPU 上发生的事情,我推测 CUDA 设备(cuda 调用类似但没有刷新,所以如果 OCL 驱动程序直接映射它们,它将立即刷新每个排队的命令)
    猜你喜欢
    • 1970-01-01
    • 2020-03-15
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多