OpenCL缓冲区创建

OpenCL缓冲区创建,opencl,buffer-objects,Opencl,Buffer Objects,我是OpenCL的新手,虽然到目前为止我已经了解了一切,但我在理解缓冲区对象如何工作方面遇到了困难 我不知道缓冲区对象存储在哪里。问题中指出: 如果您只有一台设备,可能(99.99%)会在设备中。(在极少数情况下,如果设备暂时没有足够的内存,它可能位于主机中) 对我来说,这意味着缓冲区对象存储在设备内存中。但是,正如StackOverflow问题中所述,如果在clCreateBuffer中使用标志CL\u MEM\u ALLOC\u HOST\u PTR,则使用的内存很可能是固定内存。我的理解是

我是OpenCL的新手,虽然到目前为止我已经了解了一切,但我在理解缓冲区对象如何工作方面遇到了困难

我不知道缓冲区对象存储在哪里。问题中指出:

如果您只有一台设备,可能(99.99%)会在设备中。(在极少数情况下,如果设备暂时没有足够的内存,它可能位于主机中)

对我来说,这意味着缓冲区对象存储在设备内存中。但是,正如StackOverflow问题中所述,如果在
clCreateBuffer
中使用标志
CL\u MEM\u ALLOC\u HOST\u PTR
,则使用的内存很可能是固定内存。我的理解是,当内存被固定时,它不会被交换出去。这意味着固定内存必须位于RAM中,而不是设备内存中

那么到底发生了什么

我想知道的是,这些旗帜有什么作用:

  • CL\u MEM\u USE\u HOST\u PTR
  • CL\u MEM\u COPY\u HOST\u PTR
  • CL\u MEM\u ALLOC\u HOST\u PTR
暗示缓冲区的位置


谢谢

让我们先看一下以下签名:

这里没有为OpenCL运行时提供确切的设备的参数,因为上下文可以有多个设备。当我们使用缓冲区对象时,运行时才知道,例如,从缓冲区对象读取/写入缓冲区对象,因为这些操作需要连接到特定设备的命令队列

每个内存对象都驻留在主机内存或上下文设备的一个内存中,运行时可能会根据需要迁移它因此,一般来说,每个内存对象在OpenCL运行时中都可能有一段内部主机内存。运行时的实际操作取决于实现,因此我们不能做太多假设,也不能得到可移植的保证。这意味着关于固定等的所有内容都依赖于实现,您只能期望最好的结果,但要避免那些肯定会阻止使用固定内存的模式

为什么需要固定内存? 固定内存意味着,进程地址空间中内存页的虚拟地址有固定的转换为RAM的物理内存地址。这允许使用PCIe在GPU的设备内存和CPU内存之间进行DMA(直接内存访问)传输(在物理地址上操作)。DMA降低了CPU负载,并可能提高复制速度。因此,我们希望固定OpenCL内存对象的内部主机存储,以提高OpenCL内存对象的内部主机存储和设备内存之间的数据传输性能

作为一个基本的经验法则:如果您的运行时分配主机内存,它可能会被固定。如果您在应用程序代码中分配它,运行时将悲观地假设它没有被固定——这通常是正确的假设

CL_MEM_USE_HOST_PTR

允许我们为OpenCL实现提供内存,用于对象的内部主机存储。这并不意味着如果我们调用内核,内存对象将不会迁移到设备内存中。由于该内存是用户提供的,运行时不能假定它是固定的。这可能会导致在设备传输之前在未固定的内部主机存储和固定的缓冲区之间增加一个副本,以便为主机设备传输启用DMA

CL_MEM_ALLOC_HOST_PTR

我们告诉运行时为对象分配主机内存它可以被钉住

CL_MEM_COPY_HOST_PTR

我们提供主机内存来复制和初始化缓冲区,而不是在内部使用它。我们还可以将它与
CL\u MEM\u ALLOC\u HOST\u PTR
结合使用。运行时将为内部主机存储分配内存可以将其固定。

希望这能有所帮助。

这个主题(故意?)含糊不清,给实现者留下了很多自由。因此,除非您针对的OpenCL实现对标志做出明确的保证,否则您应该将它们视为建议

首先,
CL\u MEM\u COPY\u HOST\u PTR
实际上与分配无关,它只是意味着您希望
clCreateBuffer
用传递给调用的
HOST\u PTR
上的内存内容预填充分配的内存。这就好像您使用
host\u ptr=NULL
调用了
clCreateBuffer
,但没有此标志,然后进行了一次阻塞调用以写入整个缓冲区

关于分配方式:

  • CL\u MEM\u USE\u HOST\u PTR
    -这意味着您已经预先分配了一些内存,并正确对齐,希望将其用作缓冲区的后备内存。如果设备不支持直接访问主机内存,或者如果驱动程序决定到VRAM的卷影复制比直接访问系统内存更高效,则实现仍然可以在缓冲区和分配的内存之间分配设备内存和来回复制。但在可以直接从系统内存读取的实现中,这是零拷贝缓冲区的一个选项
  • CL\u MEM\u ALLOC\u HOST\u PTR
    -这是一个提示,告诉OpenCL实现您计划通过将缓冲区映射到主机地址空间从主机端访问缓冲区,但与
    CL\u MEM\u USE\u HOST\u PTR
    不同,您将分配本身留给OpenCL实现。对于支持它的实现,这是零拷贝缓冲区的另一个选项:创建缓冲区,将其映射到主机,获取主机算法或I/O以写入映射的内存,然后取消映射并在GPU内核中使用它。与
    CL_MEM_USE_HOST_PTR
    不同,这为使用可直接映射到CPU地址空间(如PCIe条)的VRAM打开了大门
  • 默认(两个
    cl_mem clCreateBuffer(
        cl_context context,
        cl_mem_flags flags,
        size_t size,
        void *host_ptr,
        cl_int *errcode_ret)