1

我在基于 NVidia 的 OpenCL 架构上开发了一个 C++ 应用程序,并希望将其分发给最终用户。

不幸的是,使用 ATI 卡的用户似乎无法运行我的游戏,因为包含我的 OpenCL 代码的 dll 甚至无法加载(动态),而使用 NVidia 驱动程序的用户似乎能够加载我的 dll。

发布“可在任何地方运行”的基于 OpenCL 的应用程序时,推荐的“最佳实践”是什么?应用程序提供商是否可以插入所有 dll 以使所有用户都能使用该应用程序,或者来自不同 OpenCL 架构的用户是否被迫下载该架构的 OpenCL SDK?

非常感谢!

编辑:奇怪的是,通过将 NVCuda.dll 添加到我的构建中解决了丢失的 dll 依赖项。(想删除它!)然而,这里提供的答案对于构建可以在大多数平台上运行的 OpenCL 应用程序的“最佳实践”非常有用......

4

3 回答 3

1

他们需要 GPU 驱动程序。对于 Intel CPU,他们可能会手动下载必要的二进制文件。

AMD 设备编译器的编译操作需要一些时间,而 Nvidia 可以快速编译。以 CPU 为目标时,编译时间非常短。我将一个基本的 C++ 流体和光线跟踪器模拟转换为 opencl 版本,并在 3 分钟后编译!(我的意思是设备 opencl-c 编译内核)如果你想给人们一个已经编译的项目,那么你需要拥有每一种类型的卡上您的访问权限并为所有这些文件编译和保存二进制文件。

某些 gl-cl-dx 共享操作可能在供应商之间不兼容。

不要使用特定于平台的常量,它们可能无法完全映射到其他平台上。

告诉人们您的目标 opencl 版本。

不要使用大于 256 个本地工作组大小进行 GPU 计算。AMD GPU 的最大本地工作组大小为 256,而 Nvidia 为 1024。

不要溢出私有寄存器,如果您非常需要它,请减少伪递归函数的深度。有时 AMD 编译器试图优化太多以至于它在本机设备编译时爆炸。

使用您自己的“平台和设备查询包装器”来找到合适的 gpu,而不仅仅是获取平台 [0] 或设备 [0]。用户可能有多个平台,例如 Intel 的 CPU 和 AMD 的 GPU,可能所有平台。APU 包含的 GPU 可能被称为 ACC 而不是 GPU(我不确定)

您的 kernels&buffer_transfers 隐式同步可以在您的系统上成功运行,而不能在其他系统上运行。

检查您的 dll 或应用程序是否与其他人的机器和操作系统相同。如果您的目标是 64 位并且他们有 32 位操作系统,那么它将无法正常工作。

于 2014-02-10T10:20:01.360 回答
0

AMD 最近的 Catalyst 驱动程序应该已经提供 OpenCL 支持。当然,当有人拥有不支持 OpenCL 和/或未安装最新驱动程序的旧卡时,它可能会退回到 CPU-OpenCL 或者它可能根本无法工作,分别。我不确定您可以做出哪些假设(关于您为程序声明的系统要求),但是当目标系统具有最新的驱动程序时,至少不需要自己的专用“可再发行组件”。

于 2014-02-10T10:56:14.710 回答
0

你应该做这个:

  1. 使用动态“OpenCL.dll/so”加载,这样您的用户根本不需要 OpenCL。(可选,但非常有用,您甚至可以退回到 CPU 模式。此外,它会强制您仅使用纯 OpenCL 调用)
  2. 仅使用常见的 OpenCL 方法,切勿使用依赖于其他 DLL 的公司调整方法。例如,nVIDIA 在 OpenCL 库中有很多工具,迫使您将其与 nVIDIA 库和驱动程序一起使用。例如,这些是以 . 开头的调用oclXXX()
  3. 以通用的方式编写内核和代码,不要期望每个人都有相同的工作大小、内存等。您应该能够检测情况,并使内核适应这些事实。使用就地编译内核,并在内核中添加#defines控制您的行为。然后您可以通过设置硬件检测到的功能从外部定义它们。(仅当您并不真正关心您的代码安全性时。

回答您的问题:

  • 如果需要,您需要从您使用的供应商(即:nVIDIA)重新分发 DLL,客户端必须启用正确的 OpenCL,即使它来自其他制造商也应该可以工作。
  • 最佳实践是使用干净的(与供应商无关的)OpenCL 代码,因此您不会强制客户端安装任何特定库。而且您无需安装它或将其与您的应用程序一起分发。
于 2014-02-10T15:15:18.090 回答