【问题标题】:Speedup GPU vs CPU for matrix operations加速 GPU 与 CPU 进行矩阵运算
【发布时间】:2016-12-06 19:50:39
【问题描述】:

我想知道多少 GPU 计算可以帮助我加快模拟速度。

我的代码的关键部分是矩阵乘法。基本上,代码看起来像下面的 python 代码,矩阵为 1000,for 循环很长。

import numpy as np
m_size = 1000
sim_length = 50

a = np.random.rand(m_size, m_size)
b = np.random.rand(m_size, m_size)

for j in range(sim_length):
    result = np.dot(a,b)

注意:我的矩阵很密集,大多是随机的,for 循环是用 cython 编译的。

我天真的猜测是我有两个因素:

  • 更多并行线程(当前为 1 级线程,GPU 为 100 级线程?)--> 100 级加速? [Source 已经过时了,从 2011 年开始]
  • 较低的处理器频率(当前为 3Ghz,GPU 通常为 2Ghz)--> 忽略

我认为这种观点很幼稚,所以我错过了什么?

【问题讨论】:

  • 如果你的 GPU 允许,我建议一个好的起点是 PyCUDA。我过去用 numpy 使用过的很棒的库。

标签: python gpu gpgpu matrix-multiplication


【解决方案1】:

矩阵乘法性能

如果您使用numpy,您可能正在使用其中一个 BLAS 库作为计算后端,例如 ATLAS、OpenBLAS、MKL 等。当您使用最快的 MKL 时,您可以在此处找到最近的性能基准,在最近的 Nvidia GPU K40m 和 Intel Xeon 12 核 E5-2697 v2 @ 2.70GHz 之间

https://developer.nvidia.com/cublas

其中 K40m 比 12 线程 E5-2697 快 6 倍。考虑到 MKL 在多核 CPU 上的扩展性很好。 K40m 比 1 线程 E5-2697 快约 72 倍。另请注意,1000-dim 几乎是充分利用 GPU 和 CPU 的下限。较小的矩阵尺寸通常会导致 GPU 上的性能下降更多。

如果您对numpy 使用较慢的 BLAS 后端,请说 GNU 许可的 ATLAS。然后你可以在这里找到 MKL 和 ATLAS 之间的比较

https://software.intel.com/en-us/intel-mkl/benchmarks#DGEMM-ATLAS

MKL 比 ATLAS 快 2~4 倍。

对于 Nvidia GPU,唯一广泛使用的后端是 CUDA 的 cuBLAS,因此性能不会像 ATLAS 与 MKL 那样发生太大变化。

数据传输

正如@janbrohl 所说,主机 RAM 和 GPU 设备内存之间的数据传输是影响整体性能的重要因素。这是数据传输速度的基准。

CUDA - how much slower is transferring over PCI-E?

给定矩阵大小,您实际上可以分别计算出计算和数据传输的绝对时间。这些可以帮助您更好地评估性能。

为了最大限度地提高 GPU 的性能,您可能需要重新设计程序以最大限度地减少数据传输,方法是将所有计算操作移至 GPU,而不仅仅是矩阵乘法。

【讨论】:

    【解决方案2】:

    一般来说,GPU 在高度并行的简单任务(这就是它们的用途)上比 CPU 快得多,比如乘以大矩阵,但 GPU 计算会出现一些问题:

    • 在普通 RAM 和图形 RAM 之间传输数据需要时间
    • 加载/启动 GPU 程序需要一些时间

    因此,虽然乘法本身可能快 100 倍(或更多),但实际上您可能会遇到小得多的加速甚至减速

    与 CPU 相比,GPU 的“愚蠢”问题更多,例如分支代码大幅减慢、必须手动处理缓存以及其他可能使为 GPU 编写快速程序变得非常具有挑战性的问题。

    【讨论】:

      【解决方案3】:

      使用 opencl api,我在 1280 核 HD7870(甚至不是主流桌面级 gpu)上尝试了 8k X 8k 乘以 8k X 8k 乘法,大约需要 0.99 秒,这意味着大约 5400 亿次加法和 5400 亿次乘法,这也表示 1.1 Tflops(广告中说的峰值的 40%)。高端桌面级 CPU 不包括集成 GPU,只有 0.2 - 0.3 Tflops(峰值)。因此,最好的 cpu 在性能和每瓦性能和每美元性能方面甚至无法达到中低 GPU。

      性能的关键选项:

      • 以 32x32 或 48x48 等补丁计算(对于每个具有一组线程的计算单元,因此每个线程计算补丁的一部分或列/行的所有补丁的总和)
      • 像 Strassen 的算法那样以指数级速度更快。
      • 对读、写和计算操作进行流水线化处理,因此连续迭代可以有效地叠加。
      • 针对硬件差异进行优化

      • 使用具有 1 到 4 选项的库

      【讨论】:

        猜你喜欢
        • 2020-10-29
        • 1970-01-01
        • 2021-02-01
        • 2015-10-06
        • 2018-11-23
        • 2020-03-12
        • 2013-09-02
        • 2018-05-11
        • 2018-12-22
        相关资源
        最近更新 更多