我开始学习 OpenCl。我阅读了这些链接:
https://en.wikipedia.org/wiki/OpenCL
https://github.com/KhronosGroup/OpenCL-Guide/blob/main/chapters/os_tooling.md
https://www.khronos.org/opencl/
但我不太了解 OpenCl 是通过在源代码中包含头文件的库,还是使用 OpenCl C 编译器的编译器?!
我开始学习 OpenCl。我阅读了这些链接:
https://en.wikipedia.org/wiki/OpenCL
https://github.com/KhronosGroup/OpenCL-Guide/blob/main/chapters/os_tooling.md
https://www.khronos.org/opencl/
但我不太了解 OpenCl 是通过在源代码中包含头文件的库,还是使用 OpenCl C 编译器的编译器?!
它既是库又是编译器。
作为头文件包含并链接的 OpenCL C/C++ 绑定是一个库。这些在 C/C++ 中提供了控制设备 (GPU) 的必要函数和命令。
对于设备,您编写 OpenCL C 代码。这种语言不是 C 或 C++,而是基于 C99,并且有一些特定的限制(例如只有一维数组)以及扩展(数学和向量功能)。
OpenCL 编译器位于 C/C++ 绑定和 OpenCL C 部分之间。使用 C/C++ 绑定,您可以在可执行文件的运行时使用命令 clBuildProgram(C 绑定)或 program.build(...) (C++) 运行编译器。然后在运行时将 OpenCL C 代码编译为特定于设备的程序集,这对于每个供应商都是不同的。例如,使用 Nvidia GPU,您可以查看设备的 Compiler PTX 程序集。
如果您了解 OpenGL,那么 OpenCL 的工作原理相同。
免责声明:自学知识提前。我想学习 OpenCL,发现 OpenCL 术语和你一样令人困惑。所以我做了一些痛苦的研究,直到我的第一个 OpenCL hello-world 程序开始工作。
OpenCL 是一个开放标准——即专门针对异构计算硬件的 API 规范。
该标准包含一组可在此处获得的文件。由制造商来为他们的设备实施标准并让 OpenCL 可用,例如通过 GPU 驱动程序向用户提供。也许以共享库的形式。
制造商还可以为开发人员提供使用 OpenCL 制作应用程序的工具。
这就是复杂的地方。
制造商提供 SDK - 包含上述开发人员所需的一切的软件包。(见上面的链接)。但它们对每个都是特定的——例如,没有它们的 gpu,NVIDIA SDK 将无法工作。
由于 SDK 与单一供应商绑定,因此最便携(恕我直言)的解决方案是使用所谓的Khronos 的 ICD 加载程序。它是一种“元驱动程序”,它将在运行时搜索 AMD、Intel、NVIDIA 和其他公司在系统中存在的其他 ICD;然后从我们的应用程序转发他们的呼叫。因此,作为开发人员,我们可以针对这个通用驱动程序进行开发,并使用它clGetPlatformIDs
来获取可用的平台和设备。它libOpenCL.so
至少在 Linux 上是可用的,我们应该链接它。
OpenGL 的对应物libOpenGL
,差不多,因为绝大多数 OpenGL(1.1+) 都以扩展的形式存在,并且必须单独加载,例如GLAD。从这个意义上说,GLAD 与 ICD 加载器非常相似。
同样,它不包含任何实际的“计算”代码,仅包含将所有内容转发到所选平台的 ICD 的 API 的存根实现。
我们仍然缺少头文件,幸好 Khronos 组织发布了C 头文件和C++ 绑定。但是没有什么能阻止您根据官方 API 文档自己编写它们。这将非常乏味且容易出错。
在这里,我们可以找到另一个与 OpenGL 相似的地方,因为标头也只是标准的结果,而 GLAD 直接从其 XML 版本生成它们!多么酷啊?!
要编写一个简单的 OpenCL 应用程序,我们需要:
对于 Debian,也许 Ubuntu 和其他有一个更简单的方法:
<vendor>-opencl-icd
,Linux 上的驱动程序通常不像 Windows 上那样单一,并且可能跨越许多软件包。ocl-icd-opencl-dev
其中包含 C、C++ 头文件 + 加载程序。