GPU 蛮力实现

GPU Brute-Force Implementation

我正在为以下问题寻求建议:

对于一个研究项目,我正在编写一个基于带有 (py)OpenCl 的 GPU 的强力算法。

(我知道 JTR 在那里)

现在我在 Python 中有一个蛮力生成器,它在每一轮中用单词 (amount=1024*64) 填充缓冲区。我将缓冲区传递给 GPU 内核。 GPU 正在为缓冲区中的每个值计算一个 MD5 哈希值,并将其与给定值进行比较。太棒了!

但是:

我不认为这真的是我可以从 GPU 获得的全部性能 - 或者是吗?当我必须用 CPU 填充缓冲区并将其传递给 GPU 'just' 进行哈希计算比较时,是否存在瓶颈 - 或者我错了,这已经是 fastet 或几乎是我可以获得的最快性能?

在我考虑在这里问这个问题之前,我做了很多研究。到目前为止,我在 GPU 内核上找不到暴力执行 - 为什么?

谢谢

编辑 1:

我试着用不同的方式解释我想知道的。可以说我有一台普通的电脑。在 GPU 上执行暴力算法比在 CPU 上执行速度更快(如果你做对了)。我查看了一些 GPU 暴力破解工具,但找不到在 GPU 内核上实现完整暴力破解的工具。

现在我正在将 "word packages" 传递给 GPU 并让他们在那里完成工作(哈希和比较)- 看起来这是常见的方式。 'split' 暴力算法不是更快所以 GPU 上的每个单元都会自己生成自己的 "word packages"。

我只是想知道为什么通常的方法是将带有值的包从 CPU 传递给 GPU,而不是在 GPU 上也执行 CPU 工作!是因为无法在 GPU 上拆分暴力算法,还是因为将其移植到 GPU 上的改进不值得?

关于"brute-force"方法的性能。

All i do is wondering why the common way is to pass packages with values from the CPU to the GPU instead of doing the CPU work also on the GPU work! Is it because it is not possible to split a brute-force algorithm on a GPU or isn't the improvement worth the effort to port it to the GPU?

我不知道你的算法的细节,但一般来说,在创建混合 CPU-GPU 算法之前需要考虑一些要点。仅举几例:

  • 不同的架构(最好的CPU算法可能不是最好的 GPU 算法)。
  • 额外的同步点。
  • 不同的内存空间(意味着 PCIe/network 传输)。
  • 更复杂的算法

  • 更复杂的微调。

  • 供应商政策。

不过,有很多示例同时结合了 GPU 和 CPU 的强大功能。通常,算法的顺序或高度发散部分将 运行 在 CPU 上,而同类的计算密集型部分 运行 在 GPU 上。其他应用程序使用 CPU 将输入数据预处理为更适合 GPU 处理的格式(例如,更改数据布局)。最后,还有一些以纯性能为目标的应用程序确实在 CPU 上做了大量工作,例如 MAGMA 项目。

总而言之,答案是它真的取决于你的算法的细节,如果真的有可能或者是否值得设计一个混合算法来充分利用你的 CPU-GPU 系统作为一个整体。

关于您当前方法的性能

我认为您应该将问题分为两部分:

  • 我的 GPU 内核效率高吗?
  • 我实际在 GPU 上工作了多少时间?

关于第一个,您没有提供有关您的 GPU 内核的任何信息,因此我们无法真正帮助您,但适用一般优化方法:

  1. 这是你的计算 memory/compute 绑定吗?
  2. 您距离 GPU 峰值内存带宽还有多远?

你需要从这些问题出发,才能知道你应该申请什么样的optimization/algorithm。看看 roofline performance model.

至于第二个问题,即使你没有详细说明,你的应用程序似乎在小内存传输上花费了很多时间(看看这个 article 关于如何优化内存转移)。启动 PCIe 只是为了发送几个字的开销会扼杀你从使用 GPU 设备中获得的任何性能优势。因此,发送一堆小缓冲区而不是打包大量缓冲区的大块内存通常不是可行的方法。

如果您正在寻找性能,您可能希望重叠计算和内存传输。阅读 this article 了解更多信息。

作为一般性建议,在实施任何优化之前,请花一些时间分析您的应用程序。这会为您节省很多时间。