Поиск…


Вступление

В этом разделе рассматриваются различные способы размещения данных где-нибудь, где ваше устройство может получить к нему доступ.

Чтение массива

Чтобы прочитать массив с устройства обратно на хост, один вызывает

clEnqueueReadBuffer($queue, $memobj, $blocking, $offset, $size, $target, 0, null, null);

$ Queue - это CommandQueue, который использовался для выделения памяти на устройстве. $ Memobj содержит адрес памяти устройства, $ offset и $ size, далее определяют, где и сколько данных копируется. $ Target - указатель на память хоста, в котором будут храниться данные. Целевая задача $ target должна быть выделена и иметь соответствующий размер.

Чтение текстуры

Чтение изображения почти похоже на чтение массива. Единственное отличие заключается в том, что размер и смещение должны быть трехмерными.

clEnqueueReadImage($queue, $memobj, $blocking, $offset, $size, $stride, $slice_pitch, $target, 0, null, null);

$ Stride определяет, сколько байтов имеет строка. Обычно это просто ширина * (байты на пиксель), но кто-то может захотеть изменить это, чтобы выровнять данные с банками памяти. То же самое касается $ slice_pitch, только это значение для третьего измерения.

Написание 2D-текстуры

Чтобы скопировать текстуру на устройство, необходимо выполнить два шага

  1. Выделите память на устройстве
  2. Скопируйте изображение на устройство
  _mem = clCreateImage2D($context, $mem_flags, $image_format, $width, $height, $stride, $source, &err);

$ Mem_flags определяет, как распределяется память. Это может быть только чтение, запись только или и то, и другое. Кроме того, вы можете определить, где и как распределяется память. $ width, $ height и $ stride довольно понятны.

Если ваши mem_flags копируют данные, все готово. Если вы хотите сделать это вручную в более поздней точке, вам нужно будет вызвать другую функцию, когда вы будете готовы.

err = clEnqueueWriteImage($queue, _mem, $blocking, $offset, $size, $stride, $slice_pitch, $source, 0, null, null);

$ Offset и $ size определяют область изображения, которую вы хотите скопировать в целевую память. $ Stride определяет, сколько байтов имеет строка. Обычно это просто ширина * (байты на пиксель), но кто-то может захотеть изменить это, чтобы выровнять данные с банками памяти. То же самое касается $ slice_pitch, только это значение для третьего измерения. И $ stepide, и $ slice_pitch должны соответствовать вашим входным данным.

Флаги памяти

При распределении памяти вы можете выбирать между различными режимами:

  • Только для чтения памяти
  • Запись только памяти
  • Чтение / запись памяти

Память только для чтения выделяется в области памяти __constant, а две другие - в нормальном __global регионе.

В дополнение к доступности вы можете определить, где выделена ваша память.

  • Не указано: Ваша память распределена в памяти устройства, как и следовало ожидать. Указатель $ source может быть установлен в null.
  • CL_MEM_USE_HOST_PTR: Это указывает устройству, что данные находятся в ОЗУ системы и не должны перемещаться. Вместо этого данные обрабатываются непосредственно в ram.
  • CL_MEM_COPY_HOST_PTR: Сообщает устройству копировать все значения по указанному адресу в память устройства или, используя CL_MEM_ALLOC_HOST_PTR, в отдельную область памяти в системном табло.
  • CL_MEM_ALLOC_HOST_PTR: Сообщает устройству о распределении пространства в системном RAM. Если используется как единственный параметр, указатель $ source может быть установлен в null.

Скоростной доступ к глобальной памяти устройства является самым быстрым. Но вам также нужно дважды позвонить ему, чтобы скопировать данные. Использование Host-указателя является самым медленным, в то время как Alloc_host_ptr предлагает более высокую скорость.

При использовании use_host_ptr устройство выполняет именно это: оно использует ваши данные в системном плунжере, который, конечно же, вызывается сервером os. Поэтому каждый вызов памяти должен проходить через процессор, чтобы обрабатывать потенциальные ошибки. Когда данные доступны, процессор копирует его в закрепленную память и передает его на контроллер DMA с использованием часовых тактовых импульсов процессора. Напротив, alloc_host_ptr выделяет фиксированную память в системном RAM. Эта память размещается за пределами механизма pageswap и поэтому имеет гарантированную доступность. Поэтому устройство может полностью пропустить CPU при доступе к системному плунжеру и использовать DMA для быстрой копирования данных на устройство.

Написание массива

Запись массива состоит из двух шагов:

  1. Выделение памяти
  2. Копирование данных

Чтобы выделить память, просто позвонить

_mem = clCreateBuffer($queue, $mem_flags, $size, $host_ptr, &err);

достаточно. Если вы решили скопировать указатель узла через mem_flags, все готово. В противном случае вы можете копировать данные, когда захотите.

err = clEnqueueWriteBuffer($queue, _mem, $blocking, $offset, $size, $source, 0, null, null);


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow