【问题标题】:Cupy is slower than numpyCupy 比 numpy 慢
【发布时间】:2018-12-13 03:18:47
【问题描述】:

我尝试使用 cupy 而不是 numpy 来加速我的 python 代码。这里的问题是,使用 cupy,我的代码变得非常慢。也许我在这个问题上有点天真。

也许任何人都可以在我的代码中找到瓶颈:

import cupy as np
import time as ti

def f(y, t):
    y_ = np.zeros(2 * N_1*N_2) # n: e-6, c: e-5
    for i in range(0, N_1*N_2):
        y_[i] = y[i + N_1*N_2] # n: e-7, c: e-5 or e-6
    for i in range(N_1*N_2):
        sum = -4*y[i] # n: e-7, c: e-7 after some statements e-5
        if (i + 1 in indexes) and (not (i in indi)):
            sum += y[i+1] # n: e-7, c: e-7 after some statements e-5
        if (i - 1) in indexes and (i % N_1 != 0):
            sum += y[i-1] # n: e-7, c: e-7 after some statements e-5
        if i + N_1 in indexes:
            sum += y[i+N_1] # n: e-7, c: e-7 after some statements e-5
        if i - N_1 in indexes:
            sum += y[i-N_1] # n: e-7, c: e-7 after some statements e-5
        y_[i + N_1*N_2] = sum

    return y_

def k_1(y, t, h):
    return np.asarray(f(y, t)) * h

def k_2(y, t, h):
    return np.asarray(f(np.add(np.asarray(y) , np.multiply(1/2 , k_1(y, t, h))), t + 1/2 * h)) * h

# k_2, k_4 look just like k_2, may be with an 1/2 here or there

# some init stuff is happening here

while t < T_end:
    # also some magic happening here which is just data saving
    y = np.asarray(y) + 1/6*(k_1(y, t, m) + 2*k_2(y, t, m) + 2*k_3(y, t, m) + k_4(y, t, m))
    t += m

编辑 我试图对我的代码进行基准测试,这里有一些结果,它们可以被视为代码中的注释。每个数字保留一行。单位是秒。 n:Numpy,c:CuPy,我主要是粗略估计一下顺序。 另外我测试了

np.multiply # n: e-6, c: e-5

np.add # n: e-5 or e-6, c: 0.005 or e-5

【问题讨论】:

  • 你有没有分析过你的慢速部分是什么?
  • @syntonym 我编辑了这个问题。结果非常令人惊讶。

标签: python numpy runtime gpu cupy


【解决方案1】:

您的代码示例不起作用,因为您尚未在任何地方定义 N_1N_2indexesindi。此外,代码中的 cmets 似乎并不能帮助其他人了解发生了什么。 您的代码可能不会从 numba/cupy 中受益,因为您尚未对代码中的操作进行矢量化。就目前代码的工作方式而言,列表可能与 numpy 数组一样快。

如果你摆脱你的 for 循环并改变

y_ = np.zeros(2 * N_1*N_2)
for i in range(0, N_1*N_2):
    y_[i] = y[i + N_1*N_2] 

n = N1*N2
y_ = np.zeros(2*n)
y_[:n] = y[n:2*n]

等等,你会大大加快你的代码速度。

【讨论】:

  • 我注释掉了 N_1、N_2、索引和 indi 的定义,因为 stackoverflow 不允许我发布那么多代码。我将尝试实现矢量化。
【解决方案2】:

您的代码并不慢,因为 numpy 很慢,而是因为您调用了许多 (python) 函数,并且调用函数(以及迭代和访问对象以及基本上 python 中的所有内容)在 python 中很慢。因此 cupy 不会帮助您(但可能会损害性能,因为它必须进行更多设置,例如将数据复制到 gpu)。如果您可以制定算法以使用较少的 python 函数(如另一个答案中的矢量化),这将极大地加快您的代码速度(您可能不需要 cupy)。

您还可以查看numba,它使用 llvm 在本机代码中编译您的代码。如果您这样做,请务必阅读一些文档并使用nopython=True,否则您只会将慢速cupy代码切换为慢速numba代码。

【讨论】:

  • 我也会看看你的建议。你知道return语句是否让数组留在GPU中吗?
  • 在您提出问题之前我没有见过cupy,但据我所知,数据将在GPU上,python只有一个参考。你也可以考虑写your own kernel code for cupy
猜你喜欢
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 2019-11-25
  • 1970-01-01
  • 2014-02-24
相关资源
最近更新 更多