Объекты памяти в OS X OpenCL

OpenCL использует память по-другому, чем стандартные программы. Эта глава представляет буферы памяти и изображения, поскольку они используются приложениями OpenCL. Посмотрите Создание и Управление Объектами изображения В OpenCL и Создании и Управлении Буферными Объектами В OpenCL для специфических особенностей об управлении видеопамятью и буферной памятью соответственно.

Посмотрите Используя IOSurfaces С OpenCL для специфических особенностей об использовании IOSurfaces с OpenCL.

Обзор

Как все вычислительные процессы, процессы, работающие на устройствах OpenCL, состоят из:

Для многих устройств (таких как GPUs), память OpenCL помещена в корпус в физически отличном куске кремния. Для других устройств память устройства находится физически на той же микросхеме. Независимо от его физического расположения память устройства может только быть считана и записана кодом ядра OpenCL, и память хоста может только быть считана и записана узлом.

Другими словами, даже если узел и память OpenCL физически непрерывны, память хоста отлична от памяти OpenCL. Ядра могут только получить доступ к данным в памяти устройств OpenCL. Главный компьютер может читать и записать в память устройства, но только устанавливать его и получать результаты. Во время вычисления устройство выглядит только в памяти устройства, и узел остается вне своего пути.

Когда данные были переданы ядру узлом, данные находятся на устройстве OpenCL во время выполнения. Ядро не может читать или записать в память хоста; это может только получить доступ к данным в собственной отдельной области памяти устройства.

Видимость памяти

В типичной среде мультиустройства память распределяется между устройствами. Никакое устройство не может получить доступ ко всей памяти. Рисунок 7-1 иллюстрирует пространства памяти в системе OpenCL. Каждое пространство памяти имеет различную видимость к узлу и ядру.

  Физическая память рисунка 7-1 системы OpenCL

Например, ядро OpenCL выполняется на отдельном пространстве памяти от узла, вызывающего его. Для ядра для доступа к данным это должно обработать, данные должны быть перемещены в память устройства. Однако передача данных между областями памяти, чтобы позволить различным устройствам работать может привести к значительным издержкам. Для оптимизации производительности минимизируйте переданный объем данных.

Узел указывает пространство памяти для данного буфера, когда это объявляет каждый параметр ядра.

Непротиворечивость памяти

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

OpenCL использует то, что вызывают расслабленной моделью непротиворечивости памяти, что означает что:

Поток операций управления памятью

Рисунок 7-2 иллюстрирует поток операций управления основной памятью в OpenCL.

  Поток операций Памяти рисунка 7-2

Поток операций основной памяти с OpenCL:

  1. Узел создает объекты памяти для использования OpenCL.

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

  2. Узел инициализирует содержание объектов памяти.

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

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

  3. Ядро работает на устройстве, обрабатывая данные, производя вывод.

  4. Чтения узла следуют из объектов памяти.

    Когда узел обнаруживает, что ядро выполнило свои задачи, это копирует результаты памяти ядра в память, к которой может получить доступ узел.

  5. Узел уничтожает объекты памяти.

    Как только все ядра, которым нужны объекты памяти, были выполнены, узел дает устройству команду высвобождать память, которую это отложило для ядра для использования. Например, в сценарии, где один буфер привык для ввода ко многим ядрам, каждое из которых работает много раз, код узла освобождает память, когда каждое выполнение ядра, для которого был нужен тот объект памяти, ставилось в очередь. Можно указать финализатор для объектов. Финализатор вызовет сборщик «мусора», когда это уничтожит объект. Посмотрите Установку финализатора.

Установка финализатора

Можно указать финализатор, функциональный элемент класса ссылки, который вызывает автоматически сборщик «мусора» при уничтожении объекта. Указать финализатор, который OpenCL вызовет когда память, указанная object параметр должен быть освобожден, вызвать:

void gcl_set_finalizer(void *object,
                       void (*gcl_pfn_finalizer)(void *object, void *user_data),
                       void *user_data);

Параметр

Описание

object

Буферная память или видеопамять возражают, к которому должен быть присоединен финализатор.

(*gcl_pfn_finalizer)(void *object, void *user_data)

Функция обратного вызова, которая будет выполняться сборщиком «мусора», когда это уничтожит указанное object. Параметры, переданные обратному вызову:

  • object параметр является указателем на объект буферной памяти или видеопамяти, к которому Вы хотите присоединить финализатор.

  • user_data параметр является указателем на пользовательские данные, которые будут переданы обратному вызову финализатора.

user_data

user_data параметр является указателем на пользовательские данные, которые будут переданы обратному вызову финализатора.

Перечисление 7-1 является примером того, как Вы использовали бы gcl_set_finalizer функция.

Перечисление 7-1  Используя gcl_set_finalizer

// This is the finalizer function you want OpenCL to call when the object is freed.
void my_finalizer(void* memObj,         // This is a pointer to the object whose
                                        // destruction triggered calling of this
                                        // finalizer.
                  void* importantData   // Pointer to data the finalizer will use.
                  )
{
// do something with memObj
// do something with importantData
}
...
void main() {
// Do stuff ...
 
 
void* my_mem_object = gcl_malloc(128, NULL, 0);      // GCL memory object
struct foo *special_data =
            (struct foo*)malloc(sizeof(struct foo)); // Some program-specific data
 
// Specify your finalizer callback.
gcl_set_finalizer(my_mem_object,  // Call the finalizer function when
                                  // my_mem_object is about to be freed.
                  my_finalizer,     // In particular, call the my_finalizer function
                                  // when my_my_object is about to be freed.
                  special_data    // Pass this special_data to the my_finalizer
                                  // function before my_mem_object is freed.
                  );
 
// Do more stuff ...
// ...
// and then, at some point, free the my_mem_object.
gcl_free(my_mem_object);      // Before the my_mem_object object is actually freed,
                             // OpenCL will call my_finalizer, and pass it
                             // my_mem_object and special_data.
}
 

Параметры, описывающие изображения и буферы в OS X OpenCL

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

На рисунке 7-3 память, содержащая изображение, представлена чередуемым прямоугольником, ограниченным шириной и высотой, и включает область существенного цвета в свой центр. Область (представленный существенным розовым прямоугольником, ограниченным шириной области и высотой области), указывает форму и размер части изображения, которым Вы хотите управлять. Другими словами, область является просто определенной суммой памяти, живущей при данном смещении (или источник) в изображение. Источник (x, y, z) позиция области в изображении.

  Подача рисунка 7-3 по сравнению с областью

Шаг строки является шириной области получения. Шаг строки является длиной в байтах в одной строке изображения. Обычно, шаг строки равен ширине в пикселях времен изображения размер каждого пикселя в байтах. Но иногда, по причинам производительности, это помогает использовать большую область памяти для хранения изображения, чем строго необходимо. Это проиллюстрировано на рисунке 7-3, где шаг строки немного больше, чем ширина изображения. Например, если бы изображение было 1 000 пикселей шириной, и каждый пиксель составлял 4 байта, то Ваш row_pitch составил бы 4 000 байтов. Но могло бы быть более эффективно для аппаратных средств обработать 4 096 байтов за строку, когда Вы могли указать row_pitch параметр как 4096.

slice_pitch параметр использовал в некотором OpenCL многомерные буферные функции манипулирования такой как gcl_memcpy_rect (см. Создание и Управление Буферными Объектами В OpenCL), размер в байтах 2D части, формирующей один уровень 3D изображения. Другими словами, подача части является числом байтов в шаге строки, умноженном на число байтов в высоте изображения. Установите slice_pitch параметр к 0 если изображение является двумерным.

Значение подачи части должно быть больше, чем или равным шагу строки, умноженному на высоту. Если Вы указываете slice_pitch параметр как 0, OpenCL вычисляет надлежащую подачу части, чтобы быть шагом строки, умноженным на высоту.