【发布时间】:2017-05-01 16:53:52
【问题描述】:
我正在使用 OpenCL(Xcode、英特尔 GPU),并且我正在尝试实现一个计算移动平均值和偏差的内核。我想将几个不同长度的双数组传递给内核。这是否可以实现,或者我是否需要用零填充较小的数组,以便所有数组的大小相同?
我是 OpenCL 和 GPGPU 的新手,所以请原谅我对任何术语的无知。
【问题讨论】:
标签: multithreading kernel opencl gpgpu c99
我正在使用 OpenCL(Xcode、英特尔 GPU),并且我正在尝试实现一个计算移动平均值和偏差的内核。我想将几个不同长度的双数组传递给内核。这是否可以实现,或者我是否需要用零填充较小的数组,以便所有数组的大小相同?
我是 OpenCL 和 GPGPU 的新手,所以请原谅我对任何术语的无知。
【问题讨论】:
标签: multithreading kernel opencl gpgpu c99
您可以将任何缓冲区传递给内核,内核不需要全部使用它。
例如,如果您的内核减少了一个缓冲区,您可以在运行时使用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(n) 是否从 globalWorkSize [ ] 中获取元素 n?以及如何使用get_global_size() 函数来完成不同的事情?您知道的任何教程或示例都会有所帮助。我理想的情况是传递大量数组常量,每个数组都包含可变长度数组。我的想法是通过用零填充来标准化数组的长度并将其折叠成一个非常大的数组,然后在内核中使用模运算符来推导数组变化的位置。但这对记忆来说似乎很昂贵?谢谢