介绍
OpenCL 是一种基于 C99 的语言,用于对 GPGPU 和 CPU(维基百科也提到 DSP 和 FPGA)进行编程。OpenCL 的优点是可以在 GPGPU 和 CPU 上执行相同的代码而无需任何更改,并且支持的平台数量巨大。另一方面,非专业人士使用最广泛的编程语言 VBA 仅支持在一个处理器上进行计算,不能异步执行代码。
我非常喜欢 Excel,因为它具有交互性,但有时对于大量计算,需要更多的功能。所以,我希望这篇文章能弥补这个差距,并展示如何将 GPGPU/CPU 上的多平台/多线程计算支持添加到 Excel。
这篇短文的目的是展示如何将 OpenCL 的支持添加到 VBA。由于我的需求仅限于 Excel 计算能力的提高,因此没有实施/讨论图像处理和相应的主题。对于那些喜欢开箱即用解决方案的人,有一个安装程序(仅限 Windows)可以安装ClooWrapperVBA
库并注册它。对于不信任安装程序的其他人,同样的内容也可以作为 zip 文件使用。您只需使用“ register.bat ”注册 DLL。
谁从图书馆受益?
- 在 Excel 中制作模型的爱好程序员。这就是我!
- 想学习 OpenCL,但不想安装 Visual Studio 等附加程序的人。
- 老派的科学家,他们在 Excel 中进行调查。我听说过那个武士。
要求:
- 视窗
- .NET 4.0 框架
- 已安装的 Excel
- Windows文件夹中的OpenCL.dll(通常存在于每台 Windows 计算机上)。
代码的组织方式:
- 源包含包装器的源(在 C# 中)和 VBA 代码。演示 Excel 表未附加到源。
- 安装后可以在“ C:\Program Files (x86)\ClooWrapperVBA\demo ”中找到演示Excel表格。
- 如果您想自己编译 C# 源代码,可以在文件夹“ demo ”的 zip 文件中找到演示 Excel 表。
让我们从一个用 OpenCL 编写的执行矩阵乘法代码的简单程序开始。
Dim clooConfiguration As New ClooWrapperVBA.Configuration
首先,检查我们可以使用哪些硬件会很有趣。下面的代码片段遍历所有可用平台和每个平台内的所有设备并获取它们的配置:
重要的配置设置是:
deviceType
(“GPU”/“CPU”)maxComputeUnits
- 可以使用的处理器/线程数deviceAvailable
compilerAvailable
请注意,如果函数执行成功,则返回SetPlatform
and函数,否则返回。SetDevice
true
false
如果没有找到平台或设备,则检查OpenCL.dll是否存在于“ Windows ”文件夹中(通常在“ C:\Windows\ ”中)。如果“ Windows ”文件夹中没有OpenCL.dll ,请从其他计算机或 Google 复制它。无论如何都要进行防病毒检查!另一个可能的原因是 GPGPU/CPU 驱动程序太旧,OpenCL 不支持。谷歌你的 CPU / GPGPU 的最新驱动程序。
OpenCL 中的矩阵乘法
现在,让我们使用可以编译 OpenCL 源的第一个可用设备将两个浮点矩阵 M1[p, q] 和 M2[q, r] 相乘。
首先,将读取 OpenCL 源代码。
参数是:
第一个参数,参数索引,从0
第一个参数开始,并且必须为下一个参数增加。以正确的顺序设置变量也很重要。首先,带有参数 index 的变量0
,然后是带有参数 index的变量1
,依此类推。
sources
- 来源为纯文本,在上一步从文件中读取。- 第二个参数 ("") 包含编译器选项。在最简单的情况下,它可以是空的("",not
null
orNothing
)。在常用的编译器选项中,如“-w
”(禁止所有警告信息),您也可以在这里定义常用的常量(“-D
name=definition”)并在 OpenCL 代码中使用。编译器选项的完整列表可以在Khronos 网页上找到。 - 第五个参数 ,
cpuCounter
定义某种特定类型(“CPU
”或“GPU
”)的设备索引。由于您的平台可以有数千个不同类型的设备,因此此参数区分相同类型的不同设备。 buildLogs
显示当前编译器日志。检查它是否包含任何错误很重要。对我来说,当我开发自己的第一个 OpenCL 代码时,检查构建日志中的警告非常有帮助。这些警告主要是内核在执行期间崩溃的原因。-
要设置内核参数,有六个函数:
- 设置数组:
SetMemoryArgument_Long
(对应于 C# 中的整数数组)SetMemoryArgument_Single
(对应于 C# 中的浮点数组)SetMemoryArgument_Double
- 要设置值:
SetValueArgument_Long
(对应于 C# 中的整数)SetValueArgument_Single
(对应于C#中的float)SetValueArgument_Double
globalWorkSize(0) = p
globalWorkSize(1) = r
最后,我们可以开始内核执行。该函数ExecuteSync
仅在其执行完成后才返回 VBA。