编写CUDA应用程序时,您可以在驱动程序级别或运行时级别工作,如此图像所示(库是CUFFT和CUBLAS用于高级数学运算):
(来源:tomshw.it)
我认为两者之间的权衡是提高低级API的性能,但代价是代码的复杂性增加。有什么具体的差异,是否有任何重要的事情你不能用高级API?
我正在使用CUDA.net与C#进行互操作,它是作为驱动程序API的副本构建的。这鼓励在C#中编写许多相当复杂的代码,而使用运行时API的C ++等效代码更简单。这样做有什么可以赢的吗?我能看到的一个好处是,将智能错误处理与其余的C#代码集成起来更容易。
答案 0 :(得分:36)
CUDA运行时可以将CUDA内核编译并链接到可执行文件中。这意味着您不必在应用程序中分发cubin文件,也不必通过驱动程序API处理它们。如您所知,它通常更容易使用。
相比之下,驱动程序API更难编程,但可以更好地控制CUDA的使用方式。程序员必须直接处理初始化,模块加载等。
显然,通过驱动程序API可以查询比通过运行时API更详细的设备信息。例如,只能通过驱动程序API查询设备上可用的空闲内存。
来自CUDA程序员指南:
它由两个API组成:
- 一种称为CUDA驱动程序API的低级API,
- 一个更高级别的API,称为CUDA运行时API,它是在...之上实现的 CUDA驱动程序API。
这些API是互斥的:应用程序应使用其中一个或 其他
CUDA运行时通过提供隐式来简化设备代码管理 初始化,上下文管理和模块管理。 C主机代码 由nvcc生成的是基于CUDA运行时(参见第4.2.5节),所以 链接到此代码的应用程序必须使用CUDA运行时API。
相比之下,CUDA驱动程序API需要更多代码,更难编程和 debug,但提供更好的控制级别,并且与语言无关,因为它只是 处理cubin对象(参见第4.2.5节)。特别是,它更难 自执行以来,使用CUDA驱动程序API配置和启动内核 必须使用显式函数调用指定配置和内核参数 而不是第4.2.3节中描述的执行配置语法。还有,设备 仿真(参见第4.5.2.9节)不适用于CUDA驱动程序API。
API之间没有明显的性能差异。你的内核如何使用内存以及它们在GPU上的布局(在warp和block中)将产生更明显的效果。
答案 1 :(得分:19)
我发现,为了在多线程应用程序中部署库,对驱动程序API提供的CUDA上下文的控制至关重要。我的大多数客户都希望将GPU加速集成到现有应用程序中,而现在几乎所有应用程序都是多线程的。由于我无法保证所有GPU代码都将从同一个线程初始化,执行和解除分配,因此我不得不使用驱动程序API。
我最初尝试在运行时API中进行各种解决方法都导致失败,有时以惊人的方式 - 我发现我可以反复,通过执行来自不同线程的错误的CUDA调用来立即重启机器。
由于我们通过Driver API迁移了所有内容,所以一切都很顺利。
Ĵ
答案 2 :(得分:3)
需要注意的几件重要事项:
首先,API之间的差异仅适用于主机端代码。内核完全相同。在主机端,驱动程序api的复杂性非常微不足道,根本区别在于:
在驱动程序api中,您可以访问运行时api类似上下文中不可用的功能。
模拟器仅适用于为运行时api编写的代码。
哦,目前cudpp是一个非常方便的库,只适用于运行时api。
答案 3 :(得分:0)
参数对齐和驱动程序API存在一些实际问题。有关更多信息,请查看CUDA 2.2 beta(或更高版本)文档。