VHristov
VHristov

Reputation: 1089

Memory management in OpenCL

When I started programming in OpenCL I used the following approach for providing data to my kernels:

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);

This obviously required me to partition my data in chunks, ensuring that each chunk would fit into the device memory. After performing the computations, I'd read out the data with clEnqueueReadBuffer(). However, at some point I realised I could just use the following line:

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

When doing this, the partitioning of the data became obsolete. And to my surprise, I experienced a great boost in performance. That is something I don't understand. From what I got, when using a host pointer, the device memory is working as a cache, but all the data still needs to be copied to it for processing and then copied back to main memory once finished. How come using an explicit copy ( clEnqueRead/WriteBuffer ) is an order of magnitude slower, when in my mind it should be basically the same? Am I missing something?

Thanks.

Upvotes: 5

Views: 4453

Answers (2)

Adam Gawne-Cain
Adam Gawne-Cain

Reputation: 1690

In some cases the CPU and GPU can share the same physical DRAM memory. For example, if the memory block satisfies CPU and GPU alignment rules then Intel interprets CL_MEM_USE_HOST_PTR as permission to share physical DRAM between CPU and GPU, so there is no actual copying of data. Obviously, that's very fast!

Here is a link that explains it:

https://software.intel.com/en-us/articles/getting-the-most-from-opencl-12-how-to-increase-performance-by-minimizing-buffer-copies-on-intel-processor-graphics

PS I know my reply is far too old for OP, but other readers may be interested.

Upvotes: 2

Dr. Snoopy
Dr. Snoopy

Reputation: 56357

Yes, you're missing the CL_TRUE in the clEnqueueWriteBuffer call. This makes the write operation blocking, which stalls the CPU while the copy is made. Using the host pointer, the OpenCL implementation can "optimize" the copy by making it asynchronous, thus in overall the performance is better.

Note that this depends on the CL implementation, and there's no guarantee that will be faster/equal/slower.

Upvotes: 3

Related Questions