OpenCL Создание буфера - PullRequest
       25

OpenCL Создание буфера

0 голосов
/ 26 ноября 2018

Я довольно новичок в OpenCL, и хотя до сих пор я все понял, но у меня возникают проблемы с пониманием работы буферных объектов.

Я не понял, где хранится буферный объект.В этом вопросе StackOverflow указано, что:

Если у вас есть только одно устройство , вероятно (99,99%) будет в нем.(В редких случаях это может быть на хосте, если устройству пока не хватает памяти)

Для меня это означает, что объекты буфера хранятся в памяти устройства.Однако, как указано в этом вопросе StackOverflow, если в clCreateBuffer используется флаг CL_MEM_ALLOC_HOST_PTR, используемая память, скорее всего, будет закреплена в памяти.Насколько я понимаю, когда память закреплена, она не будет выгружена.Это означает, что закрепленная память ДОЛЖНА быть расположена в ОЗУ, а не в памяти устройства.

Так что же на самом деле происходит?

Что бы я хотел знать, для чего нужны флаги:

  • CL_MEM_USE_HOST_PTR
  • CL_MEM_COPY_HOST_PTR
  • CL_MEM_ALLOC_HOST_PTR

подразумевают расположение буфера.

Спасибо

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Спецификация (намеренно?) Неопределенна в этой теме, оставляя большую свободу для разработчиков.Поэтому, если реализация OpenCL, на которую вы нацеливаетесь, не дает явных гарантий для флагов, вы должны обращаться с ними как с рекомендациями.

Прежде всего, CL_MEM_COPY_HOST_PTR на самом деле не имеет ничего общего с распределением, это просто означает, что вы хотели бы clCreateBuffer, чтобы предварительно заполнить выделенную память содержимым памяти на host_ptr, который вы передали вызову.Это как если бы вы вызвали clCreateBuffer с host_ptr = NULL и без этого флага, а затем сделали блокирующий clEnqueueWriteBuffer вызов для записи всего буфера.

Относительно режимов выделения:

  • CL_MEM_USE_HOST_PTR - это означает, что вы предварительно выделили некоторую память, правильно выровняли и хотели бы использовать ее в качестве резервной памяти для буфера.Реализация все еще может распределять память устройства и копировать туда и обратно между вашим буфером и выделенной памятью, если устройство не поддерживает прямой доступ к памяти хоста, или если драйвер решает, что теневое копирование в VRAM будет более эффективным, чем прямой доступ к системеобъем памяти.В реализациях, которые может считывать непосредственно из системной памяти, это один из вариантов для буферов нулевого копирования.
  • CL_MEM_ALLOC_HOST_PTR - это подсказка, чтобы сообщить реализации OpenCL, что выПланируя доступ к буферу со стороны хоста, отображая его в адресное пространство хоста, но в отличие от CL_MEM_USE_HOST_PTR, вы оставляете само выделение для реализации OpenCL.Для реализаций, которые его поддерживают, это еще одна опция для нулевых буферов копирования: создайте буфер, сопоставьте его с хостом, получите алгоритм хоста или ввод / вывод для записи в отображенную память, затем снимите карту и используйте ее в ядре GPU,В отличие от CL_MEM_USE_HOST_PTR, это оставляет дверь открытой для использования VRAM, который может быть сопоставлен непосредственно с адресным пространством ЦП (например, PCIe BARs).
  • По умолчанию (ни один из вышеперечисленных 2): выделять там, где это наиболее удобно дляустройство.Обычно это VRAM, и если отображение памяти в память хоста не поддерживается устройством, это обычно означает, что если вы отобразите его в адресное пространство хоста, у вас получится 2 копии буфера, одна в VRAM и одна в системной памяти,в то время как реализация OpenCL внутренне копирует туда и обратно между 2.

Обратите внимание, что реализация также может использовать любые предоставленные флаги доступа (CL_MEM_HOST_WRITE_ONLY, CL_MEM_HOST_READ_ONLY, CL_MEM_HOST_NO_ACCESS, CL_MEM_WRITE_ONLY,CL_MEM_READ_ONLY и CL_MEM_READ_WRITE), чтобы повлиять на решение о том, где распределять память.

Наконец, в отношении «закрепленной» памяти: многие современные системы имеют IOMMU, а когда он активен, доступ к системной памяти с устройствможет вызвать сбои страниц IOMMU, поэтому технически память хоста даже не должна быть резидентной.В любом случае реализация OpenCL обычно глубоко интегрирована с драйвером устройства уровня ядра, который обычно может фиксировать диапазоны системной памяти (исключая их из подкачки) по требованию.Поэтому, если вы используете CL_MEM_USE_HOST_PTR, вам просто нужно убедиться, что вы предоставили надлежащим образом выровненную память, а реализация позаботится о закреплении за вами.

0 голосов
/ 26 ноября 2018

Давайте сначала посмотрим на сигнатуру 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.Среда выполнения выделит память для внутреннего хранилища хоста. Это может быть закреплено.

Надеюсь, это поможет.

...