在 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 中寻址向量元素的主要内容,如果未能解决你的问题,请参考以下文章

OpenCL (Cuda) 中的元素操作

当我尝试增加矩阵大小时,在 AMD openCL/C 中实现矩阵向量乘法会导致系统死机

如何在 opencl c 内核上使用 vector<char**> 缓冲区或使用此向量设置 SVM?

在c ++中返回指向向量元素的指针

C ++:在向量中插入啥 - 指针或引用,向量何时复制它的元素?

OpenCL中的便携式矢量移位/排列?