Давайте сначала посмотрим на сигнатуру clCreateBuffer :
cl_mem clCreateBuffer(
cl_context context,
cl_mem_flags flags,
size_t size,
void *host_ptr,
cl_int *errcode_ret)
Здесь нет аргумента, который бы предоставил среде выполнения OpenCL точное устройство, в память которого буфер долженбыть поставленным, поскольку контекст может иметь несколько устройств.Среда выполнения знает только, как только мы используем буферный объект, например, для чтения / записи из / в него, так как эти операции нуждаются в очереди команд, которая связана с конкретным устройством.
Каждый объект памяти находится либо в памяти хоста, либо в одной из памяти устройства контекста, и среда выполнения может переносить его по мере необходимости. Таким образом, в общем случае каждый объект памяти может иметь часть внутренней памяти хоста в среде выполнения OpenCL. Что на самом деле выполняет среда выполнения, зависит от реализации, поэтому мы не можем сделать слишком много предположений и не получить переносимых гарантий.Это означает, что все о закреплении и т. Д. Зависит от реализации, и вы можете только надеяться на лучшее, но избегать шаблонов, которые определенно предотвратят использование закрепленной памяти.
Почему мы хотим закрепить память? Закрепленная память означает, что виртуальный адрес страницы нашей памяти в адресном пространстве нашего процесса имеет фиксированный перевод в адрес физической памяти ОЗУ.Это обеспечивает передачу данных DMA (прямой доступ к памяти) (которые работают по физическим адресам) между памятью устройства графического процессора и памятью процессора с использованием PCIe.DMA снижает нагрузку на процессор и, возможно, увеличивает скорость копирования.Поэтому мы хотим, чтобы хранилище внутреннего хоста наших объектов памяти OpenCL было закреплено, чтобы повысить производительность передачи данных между внутренним хранилищем хоста и памятью устройства объекта памяти OpenCL.
Основное правило: если ваша среда выполнения выделяет память хоста, она может быть закреплена.Если вы выделите его в коде приложения, среда выполнения будет пессимистично предполагать, что он не закреплен - что обычно является правильным предположением.
CL_MEM_USE_HOST_PTR
Позволяет выделить память для реализации OpenCL для внутреннего хост-хранилища объекта.Это не означает, что объект памяти не будет перенесен в память устройства, если мы вызовем ядро.Так как эта память предоставляется пользователем, среда выполнения не может предположить, что она закреплена .Это может привести к дополнительной копии между незакрепленным внутренним хранилищем хоста и закрепленным буфером перед передачей устройства, чтобы включить DMA для передач хост-устройства.
CL_MEM_ALLOC_HOST_PTR
Мы говорим среде выполнения выделить память хоста для объекта. Может быть закреплено .
CL_MEM_COPY_HOST_PTR
Мы предоставляем хост-память для копирования-инициализации нашего буфера, а не для его внутреннего использования.Мы также можем комбинировать его с CL_MEM_ALLOC_HOST_PTR
.Среда выполнения выделит память для внутреннего хранилища хоста. Это может быть закреплено.
Надеюсь, это поможет.