OpenCL上下文是什么意思?为什么它们有意义?

OpenCL上下文是什么意思?为什么它们有意义?,opencl,Opencl,OpenCLAPI涉及创建“执行上下文”,许多API调用都需要上下文和设备ID 但是这些有什么用呢?我们使用一系列设备创建上下文。这不是一个非常人工的构造吗?我的意思是,如果我们有,比如说,所有设备共享一些公共内存空间作为预定义的上下文,那么我想这是有道理的。但除此之外,为什么不让特定于设备的OpenCL API完全忽略上下文,而多设备相关的API发生在平台级别 现在,如果您告诉我“哦,但是上下文有X或doy,哪些设备和平台没有”——请解释为什么X或Y不应该在设备上下文或平台上下文中。(Open

OpenCLAPI涉及创建“执行上下文”,许多API调用都需要上下文和设备ID

但是这些有什么用呢?我们使用一系列设备创建上下文。这不是一个非常人工的构造吗?我的意思是,如果我们有,比如说,所有设备共享一些公共内存空间作为预定义的上下文,那么我想这是有道理的。但除此之外,为什么不让特定于设备的OpenCL API完全忽略上下文,而多设备相关的API发生在平台级别

现在,如果您告诉我“哦,但是上下文有X或doy,哪些设备和平台没有”——请解释为什么X或Y不应该在设备上下文或平台上下文中。(OpenCL 1.2)列出了:

  • 命令队列:特定于设备
  • 内存:可以是多个设备,但由于在上下文中选择设备是任意的,因此它似乎不是正确的抽象
  • 程序和内核对象:为什么这不是特定于设备的?(或者-设备和用户特定?)
  • 用于“在上下文中指定的一个或多个设备上执行内核”:不清楚特定于设备有什么问题(如果我们更关心同步化,则为平台范围)

PS-CUDA也有“上下文”,但它们是线程特定和设备特定的,并且封装了策略,如“同步时该线程是否会阻塞?”或“调度GPU工作后该线程是否会屈服”等。)

为什么上下文需要设备作为参数?因为有些平台有多个设备(例如:AMD有CPU设备和GPU设备)。如果删除该功能,则唯一的选项是:

  • 缓冲区仅适用于每个设备: 这意味着在CL程序中不可能使用多个设备。或者是这样,但你需要在它们之间进行明确的复制

    • 一开始似乎还可以。但是尝试在8GPU系统中进行显式复制。如果您不先擦除特定GPU上的缓冲区,则呼叫也可能返回OutOfMemory并导致应用程序崩溃。要么你的应用程序是完全平衡的,要么某个特定的GPU出现瓶颈和内存饱和的可能性非常高。让API为您处理所有副本要容易得多
  • 缓冲区是每个平台的: 这意味着,在单个GPU应用程序中,您需要指定缓冲区应复制到的位置。 解决方案也可以是显式复制。和以前一样的问题

此外,上下文提供与GL上下文相同的抽象,隔离您正在使用的所有“软”资源,并在销毁时清除和销毁其中的所有内容

如果创建上下文对象的应用程序被终止或SEG_出现故障,则很容易取消资源或该应用程序的分配,而不会影响并行运行的任何其他应用程序


此外:

程序和内核对象:为什么这不是特定于设备的?(或者-设备和用户特定?)

内核已经是特定于设备的,因为它们是程序和给定设备中函数的特定实例


您可以使用同一程序生成任意数量的内核,但参数不同。这是非常有用且有意义的,而不是在每次调用中使用单个内核对象并更改其参数,而是使用多个内核实例更有意义。

CUDA始终具有类似的上下文概念。此级别的控制由驱动程序api提供给您。运行时API保存一个可由驱动程序API访问的上下文。使用多个上下文是指在不使用CUDADeviceSet的情况下销毁一个上下文的能力。@FlorentDUGUET:我会编辑我的答案,但这是一个每个设备的上下文,即多个上下文一个设备,而不是像OpenCL中那样的多个。而且,那些CUDA上下文是特定于线程的。OpenCL是一个标准。我相信他们为会议期间讨论的一些特性留出了空间,而双子座的设计人员或其他实现人员可能希望从共享内存中获益。据我所知,在CUDA上并不是这样实现的,但OpenCL是由其他人实现的。这变成了讨论/意见。@FlorentDUGUET:但即使是其他功能的空间也有其背后的原因。您能否给出一个有意义的例子,说明这种上下文(多设备,而不是线程特定的)是如何有用的?可以创建多个上下文,一个/内核,并在它们之间使用单独内核的结果?。有人有使用多个上下文的有用示例吗?