可以跨OpenCL内核在CPU和GPU上并发运行

可以跨OpenCL内核在CPU和GPU上并发运行,opencl,gpgpu,Opencl,Gpgpu,假设我有一台计算机,它有一个多核处理器和一个GPU。我想写一个OpenCL程序,它运行在平台的所有核心上。这是可能的,还是我需要选择一个设备来运行内核?不,您不能在CPU和GPU上自动跨越内核,它要么是一个,要么是另一个 您可以这样做,但这需要手动创建和管理两个命令队列(每个设备一个) 请参阅此线程: 理论上是的,您可以,CL API允许这样做。但是平台/实现必须支持它,我不认为大多数CL实现支持它 为此,请获取CPU设备和GPU设备的cl_设备id,并使用clCreateContext创建这两

假设我有一台计算机,它有一个多核处理器和一个GPU。我想写一个OpenCL程序,它运行在平台的所有核心上。这是可能的,还是我需要选择一个设备来运行内核?

不,您不能在CPU和GPU上自动跨越内核,它要么是一个,要么是另一个

您可以这样做,但这需要手动创建和管理两个命令队列(每个设备一个)

请参阅此线程:

理论上是的,您可以,CL API允许这样做。但是平台/实现必须支持它,我不认为大多数CL实现支持它


为此,请获取CPU设备和GPU设备的cl_设备id,并使用clCreateContext创建这两个设备的上下文。

不能将一个内核扩展到多个设备。但是,如果您正在运行的代码不依赖于其他结果(即:处理16kB的数据块,这需要大量处理),那么您可以在GPU和CPU上启动相同的内核。并在GPU上放置一些块,在CPU上放置一些块

这样应该可以提高性能

您可以这样做,为CPU和GPU创建一个共享的clContext,以及2个命令队列


这并不适用于所有内核。有时,内核代码适用于所有输入数据,并且不能以部分或块的形式分开。

一个上下文只能用于一个平台。如果您的多设备代码需要跨平台工作(例如,英特尔平台CPU OpenCL和NVidia GPU),则需要单独的上下文

但是,如果GPU和CPU恰好在同一个平台上,那么可以使用一个上下文

如果您在同一平台上使用多个设备(两个相同的GPU,或来自同一制造商的两个GPU),那么您可以共享上下文—只要它们都来自单个CLGetDeviceID调用

编辑: 我应该补充一点,GPU+CPU上下文并不意味着任何自动管理的CPU+GPU执行。通常,最好让驱动程序分配一个内存缓冲区,GPU可以对其进行DMA以获得最佳性能。如果CPU和GPU位于同一上下文中,则可以跨两个设备共享这些缓冲区


你仍然需要自己分担工作量。我最喜欢的负载平衡技术是使用事件。每n个工作项,将一个事件对象附加到一个命令(或将一个标记排队),并等待您在n个工作项之前设置的事件(前一个)。如果你不必等待,那么你需要在设备上增加n,如果你必须等待,那么你应该减少n。这将限制队列深度,n将在完美深度附近徘徊以保持设备繁忙。无论如何,您都需要这样做,以避免造成GUI渲染不足。只需在每个命令队列中保留n个命令(CPU和GPU有单独的n个命令),它就会完全分开。

或者,在一个平台中不支持两个设备,但CPU有一个平台,GPU有另一个平台的系统上,您可以在这两个平台之间手动拆分工作。将部分工作发送到CPU,将部分工作发送到GPU。将大量工作项排队是一种不好的做法。原因是您将导致渲染工作项饥饿(导致令人恶心的缓慢屏幕更新),或者更糟的是,有一个看门狗将中止并重新加载视频驱动程序(触发挂起检测)。一个更好的实践(当然,如果可能的话)是拥有一个工作流,但在项目排队等待执行之后的几天内,才从项目中获取结果。这允许您限制GPU的使用,这样您就不会压倒屏幕绘图工作。