Board logo

标题: 使用 OpenCL 加速 Web 应用程序(3)内核编码 [打印本页]

作者: look_w    时间: 2018-10-18 19:55     标题: 使用 OpenCL 加速 Web 应用程序(3)内核编码

内核编码WebCL 内核代表一个可在 GPU 或者其他适用的设备上执行的函数。总体结构如下:
1
2
3
__kernel void func_name(parameter_list) {
   ...lines of code...
}




内核声明以 __kernel 开头,其返回值是 void。这就意味着该函数的输入/输出数据必须由其参数列表提供。内核函数必须按照 C99 进行编码,但是开发人员可以访问许多 WebCL 特有的数据类型和函数。
内核的数据类型内核可以访问 C 的基本数据类型,并使用向量数据类型更快速地处理数据。这些类型是以 typen 的形式提供的,type 是基本数据类型,n 是向量中该类型元素的数量(通常是 2、4、8 和 16)。
例如,一个 float4 就是一个包含 4 个浮点数的向量。如果设备支持 float4 操作,那么向量上的每个操作将会同时影响向量上的所有元素。如果不受支持,那么内核编译器将相关操作分散到受支持的设备上。
初始化一个向量和初始化一个数组类似,但使用的是圆括号(()),而不是波形括号({})。清单 8 中的代码显示了如何重新声明和初始化两个向量:int4 和 char16。
清单 8.  声明和初始化了两个向量
1
2
3
int4 vector_a = (int4)(1, 2, 3, 4);
char16 vector_b = (char16)('H', 'e', 'l', 'l', 'o',
    'P', 'r', 'o', 'g', 'r', 'a', 'm', 'm', 'e', 'r', '!');




运算符和数学函数内核通常可以访问 C 中使用的所有运算符,这就意味着,如果 vec_a 和 vec_b 具有相同的向量类型,那么 vec_a * vec_b 会返回一个包含其乘积的向量。逻辑运算符也可用,而且 (5 > 3) 在内核中返回与正则函数相同的值。如果向量牵涉到关系运算,结果为 true 时,向量的元素会被设置为 -1,结果为 false 时,则设置为 0。
如果 C 函数没有涉及到数学、逻辑或者比较运算,那么可能无法在内核中访问到它。但是内核几乎可以调用标准数学库中的所有函数,从 acos 到 sqrt。这些函数接受向量和标量。所以,要计算 vec 的 float4 的绝对值,需要调用 fabs(vec),似乎 vec 只是另一个值。
工作项函数当工作项执行内核时,它的第一个任务通常是确定自己的 ID。它可以访问内核的维数和执行内核的工作项总数。可以使用以下函数完成这项任务:
清单 9 中的内核函数显示了工作项函数在实践中的应用。
清单 9.  实践中的工作项函数
1
2
3
4
5
__kernel void example(__global float* in_array, __global float* out_array) {
   int id = get_global_id(0);
   int N = get_global_size(0);
   out_array[id] = in_array[id]/N;
}




执行这一内核的工作项是一维的,在 in_array 和 out_array 中,每个元素都有一个工作项。在执行内核时,每个工作项读取 in_array 的元素,用它除以工作项的总数,然后将结果存储到 out_array 中。简而言之,这就是 WebCL 内核的工作方式。下一节将会使用类似过程进行文本搜索。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0