CUDA Thrust 与原始内核相比如何?

How does CUDA Thrust compare to a raw kernel?

我是 GPU 编程的新手,不确定什么会导致最高效的代码。 pros/cons 使用 Thrust 与编写自定义内核并自行管理内存有何不同?

如果它有助于详细说明我的目标是什么:我有一个大矩阵,我需要为每个值执行一些向量运算。我知道我需要动态并行来完成这项任务,目前有一个自定义内核来通过调用其他内核的矩阵。我正在考虑是否应该用 Thrust 调用替换内核(例如 thrust::for_each)and/or 我是否应该在内核中使用 Thrust 进行矢量操作。

在过去的 ~12 个月里,我从主要编写 CUDA 内核到主要使用 Thrust,然后又回到主要编写 CUDA 内核。一般来说,编写自己的 CUDA 内核应该提供更好的原始性能,但在更简单的测试用例中,差异应该可以忽略不计。

Thrust 模仿 C++ STL,因此它具有许多与 STL 相同的优点和缺点。也就是说,它旨在以一种非常通用的方式对数据向量进行操作。从这个角度来看,Thrust 在某些方面比 CUDA 更好,但不应被视为 one-size-fits-all 解决方案。 Thrust 的主要优势在于抽象和可移植性等领域;您不必考虑块大小,并且很容易编写同样适用于设备或主机上数据的仿函数,而显然 CUDA 内核只能在设备内存上运行。它还具有许多非常有用的算法;不必编写自己的缩减或排序算法真是太好了,因为 Thrust 提供了这些算法的非常有效的实现。但是在引擎盖下你的数据访问模式可能不容易匹配 Thrust 的设计目的,并且 thrust 倾向于执行大量临时内存分配(这在性能上下文中通常不好;你可以破解它的内存管理模型来缓存这些临时分配,但我不建议实际这样做,只需编写内核并自己完全控制内存使用即可)。

我现在更喜欢的工作模式是几乎所有的事情都使用 CUDA,但对于特定算法(例如排序)、原型代码或我希望实现同样出色的代码,则使用 Thrust 的算法主机或设备。