我怎么知道我的Embarassingly Parallel Task是否适合GPU?

时间:2018-04-26 19:17:07

标签: python parallel-processing gpu numba

我们是说在大量行上每行需要相当轻量级的任务从根本上不适合GPU吗?

我要在行独立的表上进行一些数据处理。所以这是令人尴尬的平行。我有一个GPU所以....在天堂做的比赛?它与此示例非常相似,它计算每行每个条目的移动平均值(行是独立的。)

import numpy as np

from numba import guvectorize

@guvectorize(['void(float64[:], intp[:], float64[:])'], '(n),()->(n)')
def move_mean(a, window_arr, out):
    window_width = window_arr[0]
    asum = 0.0
    count = 0
    for i in range(window_width):
        asum += a[i]
        count += 1
        out[i] = asum / count
    for i in range(window_width, len(a)):
        asum += a[i] - a[i - window_width]
        out[i] = asum / count

arr = np.arange(2000000, dtype=np.float64).reshape(200000, 10)
print(arr)
print(move_mean(arr, 3))

就像这个例子一样,我对每一行的处理都不是很重要。相反,它循环遍历行并进行一些求和,赋值和其他一些带有一些条件逻辑的碎片。

我尝试在Numba库中使用guVectorize将其分配给Nvidia GPU。它工作正常,但我没有加速。

这种类型的任务原则上适合GPU吗?也就是说,如果我深入研究Numba并开始调整线程,块和内存管理或算法实现,理论上我应该加快速度。或者,这种问题从根本上说是不适合这种架构。

下面的答案似乎表明它不合适,但我还不太相信。

numba - guvectorize barely faster than jit

numba guvectorize target='parallel' slower than target='cpu'

1 个答案:

答案 0 :(得分:3)

你的任务显然是受内存限制的,但它并不意味着你无法从GPU中获利,但它可能不像CPU限制任务那么直接。

让我们看看常见配置并做一些数学运算:

  1. CPU-RAM内存带宽约。 24GB / s的
  2. CPU-GPU传输带宽约。 8GB / s的
  3. GPU-RAM内存带宽约。 180GB / s的
  4. 假设我们需要传输24 GB的数据来完成任务,因此我们将有以下最佳时间(是否以及如何实现这些时间是另一个问题!):

    1. 场景:仅CPU时间= 24GB / 24GB / s = 1秒。
    2. 场景:数据必须从CPU传输到GPU(24GB / 8GB / s = 3秒)并在那里处理(24GB / 180GB / s = 0.13秒)导致3.1秒。
    3. 场景:数据已经在设备上,因此只需要24GB / 180GB / s = 0.13秒。
    4. 正如人们所看到的那样,有可能加速,但仅限于3.场景 - 当您的数据已经在GPU设备上时。

      但是,实现最大带宽是一项非常具有挑战性的事业。

      例如,在CPU上逐行处理矩阵时,您希望您的数据处于行主顺序(C顺序),以便充分利用L1缓存:读取一个双倍,你实际上将8个双打加载到缓存中,并且你不希望它们从缓存中逐出,然后才能处理剩余的7个。

      另一方面,在GPU上,您希望内存访问为coalesced,例如线程0应该访问地址0,线程1 - 地址1等等。为此,数据必须按列主顺序(Fortran-order)。

      还有另一件事需要考虑:测试性能的方式。您的测试阵列只有大约2MB,因此对于L3缓存来说足够小。 L3缓存的带宽取决于用于计算的内核数量,但至少约为100GB / s - 比GPU慢很多,并且在CPU上并行化时可能要快得多。

      您需要更大的数据集才能避免被缓存行为所迷惑。

      有点偏离主题的评论:从数值的角度来看,你的算法不是很强大。

      如果窗口宽度为3,如示例所示,但行中有大约10**4个元素。因此,对于最后一个元素,该值是大约10**4个加法和减法的结果,每个加法和减法都会给该值增加一个舍入误差 - 相比之下,如果完成,则只有三个加法和#34;天真地"这是非常不同的。

      原因,它可能没有意义(对于你的例子中的连续10个元素),但有一天也可能会咬你...