Когда я начал программировать в 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 ) на порядок медленнее, хотя, на мой взгляд, оно должно быть в основном таким же? Я что-то упускаю?
Спасибо.