Вы можете передать в ядро любой буфер, ядру не нужно его использовать. Например, если ваше ядро сокращает буфер, во время выполнения вы можете запросить количество рабочих элементов (предметов для уменьшения) с помощью get_global_size(0)
. Затем вызовите ядро с соответствующими параметрами.
Пример (неоптимизированная):
__kernel reduce_step(__global float* data)
{
int id = get_global_id(0);
int size = get_global_size(0);
int size2 = size/2;
int size2p = (size+1)/2;
if(id<size2) //Only reduce up to size2, the odd element will remain in place
data[id] += data[id+size2p];
}
Тогда вы можете назвать это так.
void reduce_me(std::vector<cl_float>& data){
size_t size = data.size();
//Copy to a buffer already created, equal or bigger size than data size
// ... TODO, check sizes of buffer or change the buffer set to the kernel args.
queue.enqueueWriteBuffer(buffer,CL_FALSE,0,sizeof(cl_float)*size,data.data());
//Reduce until 1024
while(size > 1024){
queue.enqueueNDRangeKernel(reduce_kernel,cl::NullRange,cl::NDRange(size),cl::NullRange);
size /= 2;
}
//Read out and trim
queue.enqueueReadBuffer(buffer,CL_TRUE,0,sizeof(cl_float)*size,data.data());
data.resize(size);
}
так я не могу легко сказать от Хроноса спецификации, но делает 'get_global_size (п)' получить элемент п от 'globalWorkSize []'? И как вы используете функцию get_global_size() для выполнения разных задач? Любые обучающие материалы или примеры, которые вы знаете, которые могли бы помочь. Моей идеальной ситуацией было бы передать большую константу массивов, каждая из которых содержит массивы переменной длины. У меня возникла идея стандартизировать длину массивов путем заполнения нулями и свернуть его в один чрезвычайно большой массив, а затем использовать модуль оператора в ядре для получения изменений в массивах. Но это кажется дорогим для памяти? Спасибо – Zroach
Вам не нужно передавать все данные в одном массиве, если вы можете их разделить в разные массивы. Если вам нужно выполнить различную работу на разных массивах, отделите их в разных ядрах. Передача 20 буферов с 20 различными длинами, чтобы выполнить 20 различных процессов в одном ядре, не только трудно сделать, но и неоптимально, так как у вас будет много кодовых путей для ее достижения. Что я изображаю в своем коде, является примером ядра, которое выполняет процесс в буфере, размер которого известен во время выполнения и не существует ветвления. – DarkZeros
Ну, я делаю скользящие средние/отклонения на 5 разных периодов времени, вероятно, около миллиарда точек данных. Я пытался придумать некоторые умные способы избежать необходимости вызывать ядро для каждой точки данных (поскольку средние значения основаны на предыдущих точках данных), так как я уверен, что у этого есть приличная накладная цена. Как я уже сказал, моя мысль заключалась в том, чтобы свести несколько примеров в разные массивы временных периодов, а затем выполнить с помощью целочисленного div. Я проверю производительность. Также думал, что я могу что-то сделать с рабочими группами/измерениями/независимо, но я еще недостаточно образован – Zroach