是否可以跨越OpenCL内核在CPU和GPU上同时运行

问题描述:

让我们假设我有一台具有多核处理器和GPU的计算机。我想写一个运行在平台所有核心上的OpenCL程序。这是可能的还是我需要选择运行内核的单个设备?是否可以跨越OpenCL内核在CPU和GPU上同时运行

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

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

+1

或者,在一个平台上不支持两个设备,但CPU有平台且GPU有另一个平台的系统上,您可以在两者之间手动分割工作。将一些工作发送给CPU,并将一些工作发送给GPU。 – 2011-12-02 19:58:51

不,您不能在CPU和GPU上自动跨越内核,它可能是其中之一。

你可以做到这一点,但这将涉及手动创建和管理两个命令队列(每个设备一个)。

看到这个线程: http://devforums.amd.com/devforum/messageview.cfm?catid=390&threadid=124591&messid=1072238&parentid=0&FTVAR_FORUMVIEWTMP=Single

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

这样,它应该提高性能。

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

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

+0

排队大量工作项目是一种不好的做法。原因是你会导致渲染工作项目匮乏(导致令人恶心的屏幕更新),或者更糟的是,有一个看门狗会中止并重新加载视频驱动程序(触发挂起检测)。一个更好的做法(当然可能的话)是要有一系列的工作,但是在项目排队等待执行之后才能得到结果。这可以让你扼杀GPU的使用,所以你不会压倒屏幕绘图工作。 – doug65536 2013-01-03 17:09:41

一个上下文只能用于一个平台。如果您的多设备代码需要跨平台工作(例如,Intel平台CPU OpenCL和NVidia GPU),那么您需要单独的上下文。然而,如果GPU和CPU碰巧在同一个平台上,那么你可以使用一个上下文。

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

编辑: 我要补充一个GPU + CPU方面,并不意味着任何自动管理CPU + GPU执行。通常情况下,让驱动程序分配一个内存缓冲区是最佳做法,该缓冲区可以由GPU进行DMA处理以获得最佳性能。在CPU和GPU处于相同环境下的情况下,您可以在两台设备之间共享这些缓冲区。

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