45

编写 CUDA 应用程序时,您可以在驱动程序级别或运行时级别工作,如图所示(库是 CUFFT 和 CUBLAS 用于高级数学):

CUDA层模型
(来源:tomshw.it

我假设两者之间的权衡是提高低级 API 的性能,但以增加代码复杂性为代价。具体的区别是什么?有什么重要的事情是你不能用高级 API 做的?

我正在使用 CUDA.net 与 C# 进行互操作,它是作为驱动程序 API 的副本构建的。这鼓励在 C# 中编写大量相当复杂的代码,而使用运行时 API 的 C++ 等效代码会更简单。这样做有什么好处吗?我可以看到的一个好处是更容易将智能错误处理与其他 C# 代码集成。

4

4 回答 4

48

CUDA 运行时可以将您的 CUDA 内核编译和链接到可执行文件中。这意味着您不必将 cubin 文件与您的应用程序一起分发,或者处理通过驱动程序 API 加载它们。正如您所指出的,它通常更易于使用。

相比之下,驱动程序 API 更难编程,但提供了对 CUDA 使用方式的更多控制。程序员必须直接处理初始化、模块加载等。

显然,通过驱动程序 API 可以查询到比运行时 API 更详细的设备信息。例如,设备上可用的空闲内存只能通过驱动程序 API 查询。

来自 CUDA 程序员指南:

它由两个 API 组成:

  • 称为 CUDA 驱动程序 API 的低级 API,
  • 在 CUDA 驱动程序 API 之上实现的称为 CUDA 运行时 API 的更高级别的 API。

这些 API 是互斥的:应用程序应该使用其中一个或另一个。

CUDA 运行时通过提供隐式初始化、上下文管理和模块管理来简化设备代码管理。nvcc 生成的 C 主机代码基于 CUDA 运行时(参见第 4.2.5 节),因此链接到此代码的应用程序必须使用 CUDA 运行时 API。

相比之下,CUDA 驱动程序 API 需要更多代码,更难编程和调试,但提供更好的控制级别并且与语言无关,因为它只处理 cubin 对象(参见第 4.2.5 节)。特别是,使用 CUDA 驱动程序 API 配置和启动内核更加困难,因为必须使用显式函数调用而不是第 4.2.3 节中描述的执行配置语法来指定执行配置和内核参数。此外,设备模拟(参见第 4.5.2.9 节)不适用于 CUDA 驱动程序 API。

API 之间没有明显的性能差异。你的内核如何使用内存以及它们在 GPU 上的布局方式(在扭曲和块中)将产生更明显的效果。

于 2008-10-31T18:55:14.147 回答
22

我发现对于在多线程应用程序中部署库,驱动程序 API 提供的对 CUDA 上下文的控制至关重要。我的大多数客户都希望将 GPU 加速集成到现有应用程序中,而如今,几乎所有应用程序都是多线程的。由于我不能保证所有的 GPU 代码都会在同一个线程中被初始化、执行和释放,所以我不得不使用驱动 API。

我最初尝试在运行时 API 中进行各种变通方法都导致失败,有时以惊人的方式失败 - 我发现我可以通过从不同线程执行错误的 CUDA 调用集来反复、立即重启机器。

自从我们通过 Driver API 迁移所有内容后,一切都很好。

Ĵ

于 2010-03-25T22:48:36.430 回答
4

需要注意的几个重要事项:

首先,API 之间的差异仅适用于主机端代码。内核完全相同。在主机端,驱动程序 api 的复杂性非常微不足道,根本区别是:

在驱动程序 api 中,您可以访问运行时 api 中不可用的功能,例如上下文。

模拟器仅适用于为运行时 api 编写的代码。

哦,目前 cudpp 是一个非常方便的库,仅适用于运行时 api。

于 2009-03-01T14:21:54.810 回答
0

参数对齐和驱动程序 API 存在一些实际问题。查看 CUDA 2.2 beta(或更高版本)文档以获取更多信息。

于 2009-03-20T16:39:48.810 回答