主机如何在组装级别将OpenCL内核和参数发送给GPU?

时间:2018-08-26 09:34:57

标签: opencl gpu

因此,您将获得内核并进行编译。您为参数设置cl_buffer,然后将clSetKernelArg两者一起设置。

然后您将内核放入队列以运行并读回缓冲区。

现在,主机程序如何告诉GPU要运行的指令。例如我正在使用带有Radeon Pro 460的2017 MBP。在组装级别,主机进程中将调用什么指令来告诉GPU“这就是您要运行的”。哪种机制可以让GPU读取cl_buffer

实际上,如果您能为我提供所有详细说明,我将非常高兴。我是一名工具链工程师,并对GPU编程的工具链方面感到好奇,但是我发现很难在其上找到良好的资源。

2 个答案:

答案 0 :(得分:1)

几乎所有内容都通过GPU驱动程序运行。内核/着色器编译器等倾向于驻留在用户空间组件中,但是当涉及到发出DMA,内存映射和对中断(GPU事件)作出响应时,该部分至少在某种程度上被该主题所涵盖。 GPU驱动程序的基于内核的组件。

一个非常简单的解释是,内核编译器生成特定于GPU模型的代码二进制文件,该二进制文件通过DMA上传到VRAM,然后将请求添加到GPU的命令队列中,以参考VRAM运行内核该内核的存储地址。

关于OpenCL内存缓冲区,基本上可以想到3种可以实现的方式:

  1. 缓冲区存储在VRAM中,当CPU需要访问它时,该范围的VRAM被映射到PCI BAR,然后可由CPU对其进行内存映射以直接访问。
  2. 该缓冲区完全存储在系统RAM中,当GPU访问它时,它使用DMA进行读写操作。
  3. 缓冲区的副本存储在VRAM和系统RAM中; GPU使用VRAM副本,CPU使用系统RAM副本。每当一个处理器在另一个修改后需要访问该缓冲区时,就会使用DMA来复制较新的副本。

在具有UMA(Intel IGP,AMD APU,大多数移动平台等)的GPU上,VRAM和系统RAM相同,因此它们本质上可以使用方法1和2的最佳方法。

如果您想对此进行深入研究,我想说一下Linux上的开源GPU驱动程序。

答案 1 :(得分:0)

排队进入内核意味着要求OpenCL驱动程序将工作提交给专用硬件以执行。例如,在OpenCL中,您将调用clEnqueueNativeKernel API,该API会将调度计算工作负载命令添加到命令队列-cl_command_queue。

根据规格:

命令队列可用于按顺序将一组操作(称为命令)排队。 https://www.khronos.org/registry/OpenCL/specs/2.2/html/OpenCL_API.html#_command_queues

接下来,此API的实现将触发硬件处理记录在命令队列中的命令(命令队列以特定硬件理解的格式保存所有实际命令)。硬件可能有多个队列并并行处理。无论如何,在处理了队列中的工作负载之后,硬件将通过中断通知KMD驱动程序,并且KMD负责通过支持OpenCL的事件机制将此更新传播到OpenCL驱动程序,该机制允许用户跟踪工作负载的执行状态-参见{{3 }}。

要更好地了解OpenCL驱动程序如何与硬件交互,可以查看开源实现,请参阅: https://www.khronos.org/registry/OpenCL/specs/2.2/html/OpenCL_API.html#clWaitForEvents