JOCL: зачем использовать буферы? - PullRequest
2 голосов
/ 26 января 2012

Учитывая float[n] inputdata для передачи в ядро ​​OpenCL, кто-нибудь может объяснить мне разницу между следующими тремя способами передачи этого в ядро:

A)

cl_mem input = clCreateBuffer(context, CL_MEM_USE_HOST_PTR Sizeof.cl_float * n,
        inputdata, NULL);
clSetKernelArg(kernel, i, Sizeof.cl_mem, Pointer.to(input));

В)

clSetKernelArg(kernel, i, Sizeof.cl_float * n, Pointer.to(inputdata));

С)

cl_mem input = clCreateBuffer(context, CL_MEM_options_here, Sizeof.cl_float * n,
        NULL, NULL);
clEnqueueWriteBuffer(command_queue, input, CL_TRUE, 0, Sizeof.cl_float * n, 
        inputdata, 0, NULL, NULL);
clSetKernelArg(kernel, i, Sizeof.cl_mem, Pointer.to(input));

Правильно ли я понял, что разница между A) и C) заключается в том, что C) копирует весь массив один раз в начале, а затем работает с ним на GPU, в то время как A) должен загружать свои данные на лету ? Так что A) хорошо, если вам нужна только небольшая часть массива, и C) это путь, если вы все равно используете весь массив?

А как насчет Б)? Это больше похоже на А), больше похоже на С) или еще что-то другое?

Ответы [ 2 ]

1 голос
/ 26 января 2012

Да, вы не можете передать огромное количество параметров.Существует верхний предел размера всех параметров (обычно в диапазоне 50 КиБ - вы можете запросить его с помощью clGetDeviceInfo и CL_DEVICE_MAX_PARAMETER_SIZE).С помощью методов a и c вы можете передавать гораздо большие буферы (сотни мегабайт). A не является полезным для OpenCL 1.1 и ниже, так как буфер все равно будет обычно копироваться, но с OpenCL 1.2 вы можете избежать одной копии, если ваш хост иустройство одно и то же (например, вы используете CPU OpenCL runtime).

0 голосов
/ 27 января 2012

Что делает каждый метод:

A) Этот метод использует буфер хоста для хранения данных. Если вы не хотите копировать данные на устройство, но хотите использовать их на месте. Я считаю, что это возможно только на процессорных устройствах, но я не совсем уверен.

B) Передает тип __global * вашему ядру. Используйте это для ограниченного количества данных. Помните, что для версии __local / NULL эта производительность может значительно (и отрицательно) зависеть от большого количества рабочих элементов / групп. Размер ограничен CL_DEVICE_MAX_PARAMETER_SIZE. Передача NULL приведет к типу __local *, а предел будет CL_DEVICE_LOCAL_MEM_SIZE.

C) Используйте это, когда у вас есть большой (т.е. больше, чем предел метода B) объем данных, которые понадобятся вашему ядру. Это копирует данные из буфера вашего хоста в буфер устройства. Если ваши данные готовы к использованию, вы можете использовать флаг mem CL_MEM_COPY_HOST_PTR для их копирования при создании буфера cl_mem и пропустить вызов clEnqueueWriteBuffer.

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