能否同时在CPU和GPU上并行运行OpenCL内核?

4

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

4个回答

2

2
理论上是可以的,CL API 允许这样做。但平台/实现必须支持它,我认为大多数 CL 实现并不支持。
要做到这一点,需要获取 CPU 设备和 GPU 设备的 cl_device_id,并使用 clCreateContext 创建一个同时包含这两个设备的上下文。

1
或者,在不支持在一个平台上使用两个设备的系统中,但是CPU有一个平台而GPU有另一个平台时,您可以手动将工作分配给这两个设备。将一部分工作发送到CPU,将另一部分工作发送到GPU。 - Jonathan DeCarlo

2
一个上下文只能适用于一个平台。如果您的多设备代码需要跨平台工作(例如,Intel平台CPU OpenCL和NVidia GPU),那么您需要分开使用上下文。
但是,如果GPU和CPU恰好在同一平台上,则可以使用一个上下文。
如果您正在同一平台上使用多个设备(两个相同的GPU或来自同一制造商的两个GPU),则可以共享上下文-只要它们都来自单个clGetDeviceIDs调用。
编辑: 我应该补充说明GPU + CPU上下文并不意味着任何自动管理的CPU + GPU执行。通常,最佳实践是让驱动程序分配一个可以由GPU进行DMA的内存缓冲区,以获得最大性能。在CPU和GPU在同一上下文中的情况下,您将能够在两个设备之间共享这些缓冲区。
您仍然需要自行拆分工作负载。我最喜欢的负载均衡技术是使用事件。每n个工作项,将事件对象附加到命令(或排队标记),并等待您设置n个工作项之前(上一个)的事件。如果您不必等待,则需要在该设备上增加n,如果您必须等待,则应该减少n。这将限制队列深度,n将围绕保持设备繁忙的最佳深度。您需要这样做以避免导致GUI渲染饥饿。只需在每个命令队列中保留n个命令(其中CPU和GPU具有单独的n),它将完美地分割。

1

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

这样应该可以提高性能。

你可以通过创建一个共享于CPU和GPU的clContext和2个命令队列来实现。

这不适用于所有内核。有时内核代码适用于所有输入数据,并且无法分成部分或块。


将大量工作项加入队列是一种不好的做法。原因是会导致渲染工作项饥饿(导致令人作呕的缓慢屏幕更新),或者更糟糕的是,有一个看门狗会中止并重新加载视频驱动程序(触发挂起检测)。一个更好的做法(当然如果可能的话)是拥有一条工作流,但在排队执行几个项目后再获取结果。这样可以控制GPU使用率,以免压倒屏幕绘图工作。 - doug65536

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接