Управление памятью в OpenCL

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

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE, object_size, NULL, NULL);
clEnqueueWriteBuffer(cl_queue, buff, CL_TRUE, 0, object_size, (void *) object, NULL, NULL, NULL);

Это, очевидно, требовало от меня разделения данных на фрагменты, чтобы каждый фрагмент помещался в память устройства. После выполнения вычислений я считывал данные с помощью clEnqueueReadBuffer(). Однако в какой-то момент я понял, что могу просто использовать следующую строку:

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, object_size, (void*) object, NULL);

При этом секционирование данных устарело. И, к моему удивлению, я испытал значительный прирост производительности. Это то, чего я не понимаю. Из того, что я получил, при использовании указателя хоста память устройства работает как кеш, но все данные все равно нужно скопировать в нее для обработки, а затем скопировать обратно в основную память после завершения. Почему использование явного копирования ( clEnqueRead/WriteBuffer ) на порядок медленнее, хотя, на мой взгляд, оно должно быть в основном таким же? Я что-то упускаю?

Спасибо.


person VHristov    schedule 08.08.2010    source источник


Ответы (2)


Да, вам не хватает CL_TRUE в вызове clEnqueueWriteBuffer. Это блокирует операцию записи, что приводит к остановке ЦП во время копирования. Используя указатель хоста, реализация OpenCL может «оптимизировать» копию, сделав ее асинхронной, что в целом повышает производительность.

Обратите внимание, что это зависит от реализации CL, и нет гарантии, что это будет быстрее/равно/медленнее.

person Dr. Snoopy    schedule 09.08.2010
comment
Я знаю о блокирующем флаге clEnqueueRead/WriteBuffer. Однако, когда я выполнял измерения, я использовал clFinish (по крайней мере, я почти уверен, что использовал), который должен иметь тот же эффект, что и блокирующий флаг, или нет? Это, конечно, только в том случае, если обрабатывается такое же количество данных. Хм, может быть, реализация CL достаточно умна, чтобы пропустить ту часть объекта, к которой нет доступа (около 70% от него)... В любом случае, спасибо! - person VHristov; 10.08.2010

В некоторых случаях ЦП и ГП могут совместно использовать одну и ту же физическую память DRAM. Например, если блок памяти удовлетворяет правилам выравнивания ЦП и ГП, то Intel интерпретирует CL_MEM_USE_HOST_PTR как разрешение на совместное использование физической DRAM между ЦП и ГП, поэтому фактическое копирование данных не происходит. Очевидно, это очень быстро!

Вот ссылка, которая объясняет это:

https://software.intel.com/en-us/articles/получение-самого-из-opencl-12-как-увеличить-производительность-путем-минимизации-копий-буфера-intel-processor-graphics

PS Я знаю, что мой ответ слишком стар для ОП, но другим читателям это может быть интересно.

person Adam Gawne-Cain    schedule 07.01.2018