OpenCL:如何避免重复的标量/向量函数?

Posted

技术标签:

【中文标题】OpenCL:如何避免重复的标量/向量函数?【英文标题】:OpenCL: how to avoid duplicate scalar/vector functions? 【发布时间】:2020-10-06 03:48:52 【问题描述】:

OpenCL 内置数学函数接受抽象 gentype 作为参数类型,因此您只有一个 exp(x)log(x) 函数,编译器会根据您调用它们时的实际参数类型自动切换到正确的函数.

我需要编写其他数学函数来执行一组基本代数运算,例如 (log(a / b) - c) / d(没有垂直向量代数),但有时在 float 标量上,有时在 float4 向量上。有没有一种干净的方法可以只编码一次并让编译器根据参数类型进行相同的切换?

或者,如果我只编写 float 标量代码并循环使用 float4 来应用它,编译器是否能够对其进行矢量化?

【问题讨论】:

【参考方案1】:

OpenCL 基于 C 编程语言,我认为避免每种类型的代码重复的唯一方法是使用 C 风格的宏。

使用它们的一种方法是使用宏作为类型,例如:

#define vt(t,s) t##s
#define vector_type(t,s) vt(t,s)

typedef vector_type(float, VECTOR_SIZE) vfloat;

然后例如VECTOR_SIZE=4 可以传递给编译器以使用float4。但这仅适用于矢量类型。要使用 floatfloat4 需要稍微不同的宏。

或者,如果我只编写浮点标量代码并循环 float4 来应用它,编译器能向量化它吗?

可能会也可能不会,这取决于很多事情。此外,OpenCL 编译器不像 gcc 那样先进,并且可能不会在您期望它们生成矢量化代码时生成。知道的唯一方法就是尝试。

【讨论】:

【参考方案2】:

在 Intel Neo 和 Nvidia OpenCL 上,使用 LLVM 10 和 Clang 10 时,仅使用一个标量函数并在需要时在每个向量元素上展开它似乎不会产生任何减速(虽然不确定哪个编译了什么) )。

因此,标量代码似乎在需要时已正确矢量化,我不需要手动维护特定的矢量化路径。

【讨论】:

【参考方案3】:

您可以使用“C++ for OpenCL”(不是 OpenCL C++)并在内核代码中使用 C++ 模板。大多数基于 LLVM 的现代实现都支持它,但您必须检查您的特定平台。

【讨论】:

以上是关于OpenCL:如何避免重复的标量/向量函数?的主要内容,如果未能解决你的问题,请参考以下文章

OpenCL C

如何编写向量函数来应用操作 f(x,y)?

避免在 UPDATE 语句中多次调用标量函数

CUDA 内核有向量指令吗?

python:如何识别变量是数组还是标量

python中的sigmoid,可以采用标量、向量或矩阵