在 C / openCL 中寻址向量元素
Posted
技术标签:
【中文标题】在 C / openCL 中寻址向量元素【英文标题】:Adressing vector elements in C / openCL 【发布时间】:2016-01-22 14:20:42 【问题描述】:我正在 pyopenCL 中编写一个 openCL 内核,我想在其中处理向量元素。
在纯 C 中,我想要的结果是:
int i = 0;
float *vec = (float*)maalloc(sizeof(float)*4);
for (i=0;i<4;i++)
vec[i]=2*i;
在 openCL 中,向量的元素以“pythonic”点语法样式访问。
float4 vec = (float4)(0);
for (i=0;i<4,i++)
vec.si = 2*i;
/*obviously doesn't work*/
所以vec[2]
在 openCL 中变成了vec.s2
,因此使用变量访问元素不再简单。尽管如此,如何使用变量访问矢量元素?
【问题讨论】:
如果你想通过数组操作访问它,使用数组。无法使用 [] 访问向量。因为在向量的编译时需要知道元素访问。 ***.com/questions/9788806/access-vector-type-opencl 看看这个以获得一些 hacky 解决方案 您可以使用vec.s[i]
。但是,为什么要使用向量然后再次拆分它们呢?这破坏了载体的目的。就做vec = vec * (float4)(0,2,4,6);
@DarkZeros:在程序中的某个时刻,我想访问向量中的元素并对不同的元素执行不同的操作。但这不是问题的范围。不过感谢vec.s[0]
的评论。我正在寻找那个。
虽然它不是很便携,但它没有在 OpenCL 规范中定义。但是,当我在大多数当前实现中进行测试时,它起作用了。我也在写我的头顶。
【参考方案1】:
OpenCL 对主机端组件和设备端组件(内核)都支持 C,因此您可以使用 float
数组编写与第一个示例几乎完全相同的内核。内核可能如下所示:
__kernel void vectorAddition(__global float* vec)
// Get the global thread id in x dimension(eliminates loop)
size_t index = get_global_id(0);
vec[index] = 2.0f * index;
然后您可以指定要使用的线程数,以便对数组的每个元素执行此操作(使线程数与数组中的元素相同)。
OpenCL 允许使用点符号进行访问,但这是为了访问vector data types 的元素。矢量数据类型可以提供更高的性能,因为可以同时对矢量数据类型中的所有元素执行相同的操作。
例如,float4
是一个向量数据类型,它存储四个彼此相邻的 32 位浮点数以构成一个 128 位结构。然后,您可以一次对所有 4 个浮点数执行操作。
例如:
float4 v = (float4)(1.0f, 2.0f, 3.0f, 4.0f);
float4 mult_result = v * 2;
这需要一条指令同时进行四次乘法运算。 mult_result
的值为 2.0f, 4.0f, 6.0f, 8.0f
。
然后可以使用点符号来访问float4
变量的组件,例如:
float a = v.x; // a = 1.0f
float b = mult_result.y; // b = 4.0f
这里是矢量数据类型的摘要:Vector Data Type Overview。
【讨论】:
以上是关于在 C / openCL 中寻址向量元素的主要内容,如果未能解决你的问题,请参考以下文章
当我尝试增加矩阵大小时,在 AMD openCL/C 中实现矩阵向量乘法会导致系统死机
如何在 opencl c 内核上使用 vector<char**> 缓冲区或使用此向量设置 SVM?