Доступ к OpenCl MemoryBuffer с помощью OpenCl.Net lib - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть функция, которая выполняет некоторые задачи графического процессора над буфером памяти, и она работает нормально. Тем не менее, я пытаюсь повысить производительность и получить некоторую гибкость, либо получая доступ к указателю объекта IMem, возвращаемому CreateBuffer , либо напрямую используя указатель хоста, чтобы не дублировать содержимое памяти. Итак, я вижу три варианта, ни один из которых не дает мне ожидаемого результата:

1) Используйте указатель хоста, чтобы избежать дополнительного копирования:

    ErrorCode ErrCode;    
    int BuffSize = 100000000;    
    IntPtr HostPtr = Marshal.AllocHGlobal(BuffSize );

    IMem Buffer_In = Cl.CreateBuffer(myContext, MemFlags.ReadOnly | MemFlags.UseHostPtr,
                     (IntPtr)BuffSize , HostPtr , out ErrCode);

    Check_CL_Error(ErrCode);

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

2) Отображение буфера в память моего хоста:

//{...}
IMem  Buffer_In = Cl.CreateBuffer(myContext, MemFlags.ReadOnly | MemFlags.AllocHostPtr,
(IntPtr)BuffSize , out ErrCode);
Check_CL_Error(ErrCode);

InfoBuffer iBuffMap = Cl.EnqueueMapBuffer(cmdQueue, Buffer_In, Bool.False, MapFlags.Write,
IntPtr.Zero, (IntPtr)BuffSize , 0, null, out clEventWriteResult, out ErrCode);
Check_CL_Error(ErrCode);
//{...} //followed by memCopy and Unmapping

Таким образом, я мог бы скопировать только ту часть исходного буфера, которую я хочу обработать. К сожалению, вызов EnqueueMapBuffer вызывает исключение PInvokeStackImbalance , и я не могу найти причину.

3) Получить фактический указатель буфера IMem.

//{...} //Create buffer
InfoBuffer infoBufferIn = Cl.GetMemObjectInfo(Buffer_In, MemInfo.HostPtr, out ErrCode);
Check_CL_Error(ErrCode);
IntPtr bufferInPtr = infoBufferIn.CastTo<IntPtr>();

Но bufferInPtr всегда возвращает 0. На самом деле я прочитал, что это не очень хороший выбор (и я нашел некоторый код о GetMemObjectInfo и, похоже, возвращает только размер при запросе HostPtr), так что этот третий вариант почти исключен.

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

Что я делаю не так с опциями 1) и 2)? Любое решение / обходной путь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...