【问题标题】:high performance prefix sum / scan function in CUDA, looking for thrust, cuDPP library alterative [closed]CUDA中的高性能前缀求和/扫描功能,寻找推力,cuDPP库替代[关闭]
【发布时间】:2013-09-04 19:09:55
【问题描述】:

我正在为我在 CUDA 中的项目寻找高性能多扫描/多前缀求和(一个内核执行中的多行)函数。

我已经尝试过 Thrust 库中的那个,但它太慢了。使用 nvcc 调试标志 (-g -G) 编译后也会导致崩溃。

在 Thrust 失败后,我专注于 cuDPP 库,它曾经是 CUDA 工具包的一部分。 cuDPP 性能非常好,但库不是最新的 cuda 5.5,并且在使用内存检查器进行调试时,cudppMultiScan() 函数中存在一些全局内存违规问题。 (cuda 5.5、nsight 3.1、visual studio 2010、gtx 260 cc 1.3)

有人知道用什么来代替这两个库吗?

R.

【问题讨论】:

  • 你看过我们在 AccelerEyes 工作的 ArrayFire 吗?
  • 不,以前没见过,看起来很有趣!谢谢! :) 它的性能如何?是生产力更高还是以性能为导向的库?
  • 如果要使用 Thrust 扫描矩阵的行,请不要重复调用inclusive_scan。为每一行分配一个索引并使用inclusive_scan_by_key。你可以调整这个example。
  • @user1946472 对于单个向量,它要么更好(在数千个元素处),要么等于推力(在百万个元素处)。对于多个矩阵,arrayfire 启动单个内核,因此比多次启动推力更快。资料来源:我写了代码。您可以联系我(我的个人资料中的电子邮件)以获取更多信息。
  • @JaredHoberock 必须为内存绑定算法读取额外的向量并不理想。但是,这比多次启动内核要好。

标签: cuda thrust cudpp


【解决方案1】:

这些库,尤其是推力,试图尽可能通用,优化通常需要专门化:例如,算法的专门化可以将共享内存用于基本类型(如 int 或 float),但通用版本不能。碰巧在特定情况下缺少专业化!

尽可能使用这些经过良好测试的通用库是个好主意,但有时,对于某些性能关键部分,您自己的实现是一个可以考虑的选项。

在您的情况下,您希望对不同的行并行进行多次扫描。一个好的实现不会对不同的行分别运行扫描:它会对所有行的所有元素同时运行相同的内核调用。根据其索引,线程可以知道它正在处理哪一行,并将忽略该行外的所有数据。

这种特殊化需要一个返回一个吸收值的函子,以防止混合行。不过,您自己仔细实施可能会更快。

【讨论】:

    【解决方案2】:

    要编写自己的前缀扫描,您可以参考

    1. CUDA SDK 的扫描示例;
    2. N. Wilt 的第 13 章,“CUDA 手册”;
    3. S. Cook 的第 6 章,“CUDA 编程,使用 GPU 进行并行计算的开发人员指南”;
    4. Parallel Prefix Sum (Scan) with CUDA。

    要进行多前缀求和,您可以多次启动同一个内核(如 a.lasram 所建议的那样)或尝试通过 CUDA 流实现并发,尽管我不知道这对您的卡是否有效。

    【讨论】:

    • 使用流是一个绝妙的主意,但我认为启动一个内核会更好,其中每个线程会将计算“钳制”在一个选定的行中
    • 我有 231 行 1424 个浮点数,因此在单独的内核中执行每一行会导致 cudalaunch 导致的时间开销过大。 cuDPP 在我的机器(gtx260)上完成这项工作大约需要 0.11 毫秒,这对我来说是极好的结果!在性能方面,cuDPP lib 是完美的。现在我将尝试@accelereyes 建议的arrayFire 库。谢谢你的回答。
    猜你喜欢
    • 2011-05-24
    • 2012-07-18
    • 2020-04-11
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多