`clCreateBuffer`中的host_ptr参数的目的是什么

问题描述 投票:0回答:1

`clCreateBuffer中的参数host_ptr是什么意思?

cl_mem clCreateBuffer ( cl_context context,
    cl_mem_flags flags,
    size_t size,
    void *host_ptr,
    cl_int *errcode_ret)

从文档中还不清楚:

host_ptr:指向可能已由以下位置分配的缓冲区数据的指针应用程序。 host_ptr指向的缓冲区的大小必须大于或等于大小字节。

对我来说,这听起来像是主机缓冲区,它将被复制到设备缓冲区中。但是,在许多示例中,我看到此操作实际上是由clEnqueueWriteBuffer执行的,实际上没有任何内容作为clCreateBuffer参数传递给host_ptr

您能否澄清?

opencl
1个回答
0
投票

host_ptr参数有两种不同的用法,具体取决于传递给flags参数的值。使用它的两个标志是CL_MEM_USE_HOST_PTRCL_MEM_COPY_HOST_PTR。如果标志不包含任何一个,并且host_ptr不为NULL,则该函数将给出CL_INVALID_HOST_PTR错误(请参见clCreateBuffer页面底部的错误)。


CL_MEM_COPY_HOST_PTR

这基本上按照您的描述进行,它将host_ptr复制到设备内存。通过有效地组合clCreateBufferclEnqueueWriteBuffer,可以提供便利。请注意,您不需要clEnqueueWriteBuffer所需的命令队列,在使用它们之前,数据将被复制到上下文中的所有设备,多么方便!

顾名思义,这是一份COPY。如果您在设备上写入此内存,则host_ptr中的内存将永远不会看到这些写入(除非您执行clEnqueueReadBuffer)。同样,如果在创建缓冲区后写入host_ptr,则设备上的内存将不会看到这些写入(除非执行clEnqueueWriteBuffer)。

CL_MEM_USE_HOST_PTR

而不是在设备内存中创建缓冲区,OpenCL将直接使用host_ptr指向的内存。如果您的设备是PCIe连接上的专用GPU,则意味着每次您以设备代码读取或写入此内存时,都必须通过PCIe发送数据(速度较慢)。 OpenCL允许设备在内核执行期间创建数据的缓存,这有所帮助。如果您的设备像集成GPU一样与主机共享物理内存,则不应有任何此类开销。

注意,尽管您必须小心以确保内存一致性。如果在内核正在与之关联的内存上运行时主机修改了host_ptr(反之亦然),则会出现未定义的行为。


使用哪个?

这取决于您正在做什么以及正在使用什么硬件。如果您不太担心内存复制性能,并且想要一种简单安全的方法,请使用CL_MEM_COPY_HOST_PTR

如果设备通过PCIe(或其他接口),则>]

对于大型数组,通常我使用CL_MEM_COPY_HOST_PTR并根据需要排队进行读/写。如果我只是在写int或小型结构,则可以使用CL_MEM_USE_HOST_PTR,请注意内存一致性。

如果您对内存性能非常感兴趣,则可能需要研究固定内存(Reference for AMD GPUs)之类的技术。

如果设备共享主机内存(集成GPU或仅CPU设备)

如果您确信主机和设备在另一主机正在写入时不会读取,则可以将CL_MEM_USE_HOST_PTR用于任何大小的存储对象。为了获得最佳性能,您可能必须确保host_ptr对齐并且具有一定大小的倍数(对于Intel设备,在4 KB边界和64字节的倍数上对齐)。 Here是有关Intel硬件零复制的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.