Рекомендации по выделению и отображению буфера в OpenCL

0

Я немного смущен относительно того, правильно ли работает мой код с использованием буферов с открытым кодом OpenCL.

У меня есть два примера, один из которых используется CL_MEM_USE_HOST_PTR, а другой - CL_MEM_ALLOC_HOST_PTR. Оба работают и работают на моем локальном компьютере и устройствах OpenCL, но меня интересует, является ли это правильным способом выполнения сопоставления и должен ли он работать на всех устройствах OpenCL. Я особенно не уверен в примере USE_HOST_PTR.

Меня интересуют только операции с буфером/картой. Я знаю, что должен делать проверку ошибок и так далее.

CL_MEM_ALLOC_HOST_PTR:

// pointer to hold the result
int * host_ptr = malloc(size * sizeof(int));

d_mem = clCreateBuffer(context,CL_MEM_READ_WRITE|CL_MEM_ALLOC_HOST_PTR,
                       size*sizeof(cl_int), NULL, &ret);

int * map_ptr = clEnqueueMapBuffer(command_queue,d_mem,CL_TRUE,CL_MAP_WRITE,
                                   0,size*sizeof(int),0,NULL,NULL,&ret);
// initialize data
for (i=0; i<size;i++) {
  map_ptr[i] = i;
}

ret = clEnqueueUnmapMemObject(command_queue,d_mem,map_ptr,0,NULL,NULL); 

//Set OpenCL Kernel Parameters
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&d_mem);

size_t global_work[1]  = { size };
//Execute OpenCL Kernel
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, 
                             global_work, NULL, 0, 0, NULL);

map_ptr = clEnqueueMapBuffer(command_queue,d_mem,CL_TRUE,CL_MAP_READ,
                             0,size*sizeof(int),0,NULL,NULL,&ret);
// copy the data to result array 
for (i=0; i<size;i++){
  host_ptr[i] = map_ptr[i];
} 

ret = clEnqueueUnmapMemObject(command_queue,d_mem,map_ptr,0,NULL,NULL);        

// cl finish etc     

CL_MEM_USE_HOST_PTR:

// pointer to hold the result
int * host_ptr = malloc(size * sizeof(int));
int i;
for(i=0; i<size;i++) {
  host_ptr[i] = i;
}

d_mem = clCreateBuffer(context,CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR,
                       size*sizeof(cl_int), host_ptr, &ret);

// No need to map or unmap here, as we use the HOST_PTR the original data
// is already initialized into the buffer?

//Set OpenCL Kernel Parameters
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&d_mem);

size_t global_work[1]  = { size };
//Execute OpenCL Kernel
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, 
                             global_work, NULL, 0, 0, NULL);

// this returns the host_ptr so need need to save it (I assume it always will?)
// although we do need to call the map function
// to ensure the data is copied back.
// There no need to manually copy it back into host_ptr
// as it uses this by default
clEnqueueMapBuffer(command_queue,d_mem,CL_TRUE,CL_MAP_READ,
                   0,size*sizeof(int),0,NULL,NULL,&ret); 

ret = clEnqueueUnmapMemObject(command_queue,d_mem,map_ptr,0,NULL,NULL);        

// cl finish, cleanup etc
  • 0
    Да, похоже, ваше понимание верно.
Теги:
performance
memory-management
opencl

1 ответ

0
Лучший ответ

Если вы используете CL_MEM_ALLOC_HOST_PTR, у вас есть вероятность, что базовая реализация OpenCL может использовать память с записями страниц.

Это означает, что страница не может быть заменена на диск и что передача между памятью хоста и устройства будет выполнена в стиле DMA без потери циклов процессора. Поэтому в этом случае CL_MEM_ALLOC_HOST_PTR будет лучшим решением.

nVidia имеет функцию памяти с блокировкой страницы (закрепленной), и они также должны использовать ее в своей реализации OpenCL. Для AMD не уверен, что они делают то же самое. Проверьте здесь для более подробной информации.

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

  • 0
    Привет спасибо за ответ Не могли бы вы включить лучший способ реализации первого примера, который не вызвал бы проблем с производительностью? Я не совсем уверен, что понимаю, почему я не уверен, что кэшированная копия в памяти устройства используется.
  • 0
    Хм, это интересно. Я думаю, что nVidia рекомендует делать карту, распределение, запись, удаление ядра, читать согласно nvidia.com/content/cudazone/cudabrowser/downloads/papers/…, и они также рекомендуют использовать ALLOC_HOST_PTR вместо USE_HOST_PTR. Я думаю, что Intel также рекомендует использовать ALLOC_HOST_PTR, поскольку в противном случае вам необходимо обеспечить правильную границу страницы. software.intel.com/sites/landingpage/opencl/optimization-guide/… . ARM тоже: infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0538e/…
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню