OpenCL 多 GPU 缓冲区读取失败

Posted

技术标签:

【中文标题】OpenCL 多 GPU 缓冲区读取失败【英文标题】:OpenCL multiple GPU buffer read fails 【发布时间】:2014-01-02 01:27:18 【问题描述】:

我正在尝试让 2 个 Nvidia GPU 并排工作以进行 n 体模拟(来源)。我进行了适当的检测,并将所有 OpenCL 内容存储在一个结构中:

struct ocl_wrap 
  cl_event event;
  cl_program program;
  cl_kernel kernel;
  cl_command_queue command_queue;
  cl_device_id device_id;
  cl_context context;

  cl_mem masses;
  cl_mem bodies;
  cl_mem speeds;
  cl_mem newBodies;

  cl_int ret;
;

所以现在,每个设备都分配了自己的结构(它自己的上下文、队列等),并且每一步我都运行这 2 个函数:

void writeGPU() 
      clCreateBuffer() //4* 
      clSetKernelArg() //5*
      clEnqueueNDRangeKernel()

void readGPU() 
      clEnqueueReadBuffer() //2*
      clFlush()
      clReleaseMemObject() //4*

一步看起来像这样:

void step() 
  for each gpu
    writeGPU();
  runCPU();
  for each gpu
    readGPU();

每台设备都有一部分需要解决的问题。

我有一个问题,前 64 个(有时是 128 个)从一个或另一个 GPU 浮动,我尝试复制回 CPU 实际上不会复制。否则,一切正常,第一个 GPU 完美运行。有时它只是工作,但只是随机出现错误并且它不会消失。有什么建议吗?

【问题讨论】:

【参考方案1】:

此时我的猜测是,您可能没有使用 OpenCL 事件系统,甚至可能没有使用 OpenCL Memory Barriers/Fences 来获取有关 I/O 是否存在的通知读写已到达目的地并通过设置断点和等待列表来协调您的程序。如果您的系统上的 OpenCL 分发套件正常工作并且您正在使用事件系统,那么上面显示的程序序列应该类似于

// setup global event objects
// setup global markers/barriers
void writeGPU() 
      // hook event listeners to APIs
      clCreateBuffer() //4* 
      clSetKernelArg() //5*
      clEnqueueNDRangeKernel()
      // place appropriate markers/barriers

void readGPU() 
      // Many OpenCL APIs listen to events and proceed only 
      // when the `wait` condition is satisfied or 
      // barrier conditions are met.
      clEnqueueReadBuffer() //2*
      clFlush()
      clReleaseMemObject() //4*

【讨论】:

【参考方案2】:

您可能在读取完成之前查看数据。 clFlush 仅确保命令离开主机,而不是确保命令在设备上完成。解决方案:使用阻塞读取,或者使用clFinish而不是clFlush,或者使用OpenCL事件。

【讨论】:

以上是关于OpenCL 多 GPU 缓冲区读取失败的主要内容,如果未能解决你的问题,请参考以下文章

如何在OpenCL中使用缓冲区分配和映射内存机制?

OpenCL 并行缓冲区压缩障碍问题

OpenCL并行缓冲区压缩障碍问题

使用像素缓冲区对象从 gpu 异步读取数据

如何在 OpenCL 内核中更新 OpenCL-OpenGL 共享缓冲区数据?

OpenCL 部分缓冲区 DMA 读/写